之前写的直观版太占地方,借鉴别人的做一个简约版,同样可以回显,就是结构怪
前言
尖峰平谷这次使用了一个简单的自定义组件,使用$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提供了大量能使我们快速便捷地处理数据的函数和方法。