尖峰平谷布局大小缩减版(vue2+element)

之前写的直观版太占地方,借鉴别人的做一个简约版,同样可以回显,就是结构怪


前言

        尖峰平谷这次使用了一个简单的自定义组件,使用$emit+el-select实现v-model。占地更小,首先一个工厂、企业有多个尖峰平谷方案,每个方案有多个配置且方案一定是12个月,一个配置从12个月选特定几个相同月和多组尖峰平谷,下图是尖峰平谷的一个基础配置(尖时段可以有多个时间段,月份可以有相同的尖峰平谷时间段,也可以单独设置某个月的时间段;配置可以新增,但配置之间的月份不能重合,也必须是12个月,多少都不行,这里月份比较、不冲突、凑满12个月校验太简单)。


一、element滑块与选择数据的区别

        滑块是一个数组结构,而且不用考虑前一个比后一个数字大的问题,因为element已经解决了,但是这个选择不能,所以只能自己用change事件解决,将两个select变为一个基础的联动组件,因为其他的时间段选择也需要(主要原因是我想复用之前的尖峰平谷时间段校验,懒得再适配对应的js校验方法了,所以这次的校验和之前的校验大差不差)。其中滑块的数据结构与选择的数据结构如图:

 

二、组件编写

1.大概思路

        1.因为只展示24小时且时间精度为半小时没有秒,所以长度就是5位字符串长度,类似:23:59。

        2.开始时间小于结束时间,如果开始时间大于结束时间,则开始时间与结束时间换位,如果有跨天需求,可以分成两段,比如23:00-01:00分为:23:00-24:00,00:00-01:00,这样前端校验就不用太麻烦

        3.数据及时传输且回显,类似v-model

2.实现

        首先将select长度缩小,我这里是120px,已经很长了,两个选择+左边的月份选择总长度不超过700px,时间因为已经定死,所以直接使用js生成数据(如果想换别的数组,直接prop传值就行),代码:

/**
         * 时间数组赋值
         */
        maskListOn() {
            let arr = []
            // 半小时制
            for(let i = 0;i<49;i++){
                if(i % 2 == 0){
                    // 偶数显示
                    arr[i] = i/2<10? '0'+i/2 + ':00':i/2 + ':00'
                }else{
                    arr[i] = Math.floor(i/2)<10? '0'+Math.floor(i/2) + ':30':Math.floor(i/2) + ':30'
                }
            }
            this.timeList = arr.map((item,index)=>{
                // console.log(item)
                let obj = {
                    label: item,
                    value:index,
                    head:false, // 是否以当前数字为开头
                    end:false, // 是否以当前数字为结尾
                }
                return obj
            })
            // console.log(this.timeList)
        },

        通过change进行数据比较,首先明确,因为数据生成时我用了0,而js中0是false,0还是空字符串,所以if判断用强校验。而且当value1和value2可能都是0的时候不能用if(value1&&value2)来判断,因为0是false,所以你明明选了值,但是他提示你没有值。

        这个判断叙述太麻烦,我测试的勉强能用,基本就是如果是空字符串、null、undefined这类特殊的直接提示没有选择数据,之后判断开始与结束的大小,开始小,那么直接输出值,开始大,就交换开始与结束的值再输出,如果相等,则判断value1与value2是不是都是0、空字符串、null、undefined、非0数字相等,0的不用管,非0数字的清空重选,其他的出现不了,select自带的clearable会出现别的情况,所以我把clearable注了,代码:

selectChange(){
            let value1 = JSON.parse(JSON.stringify(this.value1))
            let value2 = JSON.parse(JSON.stringify(this.value2))
            if(value1&&value2 // value1和value2存在
                &&value1!==null&&value2!==null // value1和value2都不等于null
                &&value1!==undefined&&value2!==undefined // value1和value2都不等于undefined
                &&value1!==''&&value2!=='' // value1不为空并且value2不为空
                ||value1===0||value2===0
            ){
                if(value1<value2){
                    // 前一个小于后一个
                    console.log('不用修改',{a:value1,b:value2})
                    this.$emit('input',[value1,value2])
                    // return {a:value1,b:value2}
                }else if(value1>value2){
                    // 前一个小于后一个
                    let a = this.value1
                    this.value1 = this.value2
                    this.value2 = a
                    console.log('修改后:',{a:this.value1,b:this.value2})
                    this.$emit('input',[this.value1,this.value2])
                    // return {a:value1,b:value2}
                }else{
                    // 先判断都是非0
                    if(value1!==0&&value2!==0){
                        this.$message.error('两个选择相同,请重新选择')
                        this.value1 = ''
                        this.value2 = ''
                        return
                    }else{
                        if(value1===''||value2===''){
                            // 还没选择或被清空了,不管
                            console.log('没选择或被清空了')
                        }else if(value1===null||value2===null){
                            // 使用select自带的clear清空了,不管
                            console.log('使用select自带的clear清空了')
                        }else if(value1===undefined||value2===undefined){
                            // 不知道啥情况会出现
                        }else if(value1===0||value2===0){
                            console.log('其中一个是0或都是0',{a:value1,b:value2})
                            this.$emit('input',[value1,value2])
                            // return {a:this.value1,b:this.value2}
                        }else{
                            console.log(20000)
                        }
                    }
                }
            }else{
                console.log(22,this.value1,this.value2)
            }
        },

        其中使用this.$emit('input',[value1,value2])实现了v-model双向绑定

三、使用组件+绘制界面

        将月份放在左边,尖峰平谷的选择与增删放在右边,宽度定死,只有y轴有滚动条,数据结构与之前的尖峰平谷一样,因为校验方法没变,所以直接用之前的尖峰平谷的校验方法就行

尖峰平谷1天内时间段选择实现简述(vue+element纯前端)

<template>
  <div style="width: 700px;border: 1px solid #f00;text-align: center;" id="form-test">
    <el-row :gutter="20">
        <!-- 月份选择与方案新增 -->
        <el-col :span="8">
            <el-checkbox-group v-model="monthChangeList">
                <el-checkbox v-for="item in monthList" :key="item.value" :label="item.value" style="margin-bottom: 15px;">
                    {{ item.label }}
                </el-checkbox>
            </el-checkbox-group> 
        </el-col>
        <el-col :span="15">
            <el-form :model="form" size="small" label-width="30px">
                <el-form-item label="尖:">
                    <el-row v-for="(item,index) in form.tip" :key="index" :gutter="20" style="margin-bottom:20px">
                        <el-col :span="15" class="tpfv">
                            <twoSelect :list="timeList" v-model="form.tip[index]"></twoSelect>
                        </el-col>
                        <el-col :span="4">
                            <el-button type="text" @click="tipAddon" icon="el-icon-plus"></el-button>
                            <el-button v-if="index>0" type="text" @click="tipDeleteOn(index)" icon="el-icon-delete"></el-button>
                        </el-col>
                    </el-row>
                </el-form-item>
                <el-form-item label="峰:">
                    <el-row v-for="(item,index) in form.peak" :key="index" :gutter="20" style="margin-bottom:20px">
                        <el-col :span="15" class="tpfv">
                            <twoSelect :list="timeList" v-model="form.peak[index]"></twoSelect>
                        </el-col>
                        <el-col :span="4">
                            <el-button type="text" @click="peakAddon" icon="el-icon-plus"></el-button>
                            <el-button v-if="index>0" type="text" @click="peakDeleteOn(index)" icon="el-icon-delete"></el-button>
                        </el-col>
                    </el-row>
                </el-form-item>
                <el-form-item label="平:">
                    <el-row v-for="(item,index) in form.flat" :key="index" :gutter="20" style="margin-bottom:20px">
                        <el-col :span="15" class="tpfv">
                            <twoSelect :list="timeList" v-model="form.flat[index]"></twoSelect>
                        </el-col>
                        <el-col :span="4">
                            <el-button type="text" @click="flatAddon" icon="el-icon-plus"></el-button>
                            <el-button v-if="index>0" type="text" @click="flatDeleteOn(index)" icon="el-icon-delete"></el-button>
                        </el-col>
                    </el-row>
                </el-form-item>
                <el-form-item label="谷:">
                    <el-row v-for="(item,index) in form.valley" :key="index" :gutter="20" style="margin-bottom:20px">
                        <el-col :span="15" class="tpfv">
                            <twoSelect :list="timeList" v-model="form.valley[index]"></twoSelect>
                        </el-col>
                        <el-col :span="4">
                            <el-button type="text" @click="valleyAddon" icon="el-icon-plus"></el-button>
                            <el-button v-if="index>0" type="text" @click="valleyDeleteOn(index)" icon="el-icon-delete"></el-button>
                        </el-col>
                    </el-row>
                </el-form-item>
                </el-form>
        </el-col>
    </el-row>
    <el-button type="primary" @click="submitOn">确定</el-button>
  </div>
</template>

四、源码(肯定有小问题,比如必填校验、清空选项等)

免费源码


总结

提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值