使用VUE封装一年中的月份段,和一天中的小时段组件

使用VUE封装一年中的月份段,和一天中的小时段组件

需求:后台返回数据,数据为一天中的几点到几点。或一年中的几月到几月。要求前端页面显示该时间段的状态为选中状态。并可以重新进行选择。将新的时间段返回到后台进行更改
例如:
{
startTime:01:00,
endTime:18:00
}
首先放上我的图,有点丑。哈哈。
这是一天内小时段的选择器,此时后台返回的数据为{startTime:07:00,endTime:15:00}
一年中的月份段选择器,与时间段选择器同理。

实现思路

1.首先将具有这个功能的模块封装成组件的形式。并且建立它与父组件之间的通信。
2.其次使用v-model为每一个“时间点”(每一个小块)绑定数据。
3.最后在点击事件中操作数据改变“时间点”的状态即可。

上代码

//父组件代码
<template>
  <div class="TimeFenceBox">  
	 //在这里使用子组件,@childMsg="listenChildMsg"用来监测子组件选择完成后传递过来的值。
	 //:parentObj='timerId'用来将父组件上的数据发送给子组件。
     <timerChoose @childMsg="listenChildMsg" :parentObj='timerId'></timerChoose>
  </div>
</template>
<script>
//这里先引入子组件
import timerChoose from "@/components/chooseTimer/chooseTimer"; //时间选择组件
export default {
//注册子组件
  components: {
    timerChoose,
  },
  data() {
    return {
   	  startTime:'',
   	  endTime: "",
      //传递给子组件的时间段
      timerId: {
        startTime: "",
        endTime: ""
      }
    };
  },
  created() {
  //先执行自身的查询方法
  	this.getList();
  },
  methods: {
    //获取详情
    getList() {
      let that = this;
      this.$axios
        .post(
          "/apis/xxx/xxx/xxx",
          {
            xxx: xxx,
            xxx: xxx,
          },
          {
            headers: {
              "X-Zc-User-Id": that.userId,
            }
          }
        )
        .then(res => {
        //这里将拿到的数据赋值给要传递给子组件的变量。
          that.timerId.startTime =  res.startTime
          that.timerId.endTime =  res.endTime
        });
    },
    // 这里的方法是子组件执行完选择时间段的操作后,点击确定按钮向父组件传递的数据
    listenChildMsg(v1, v2) {
      this.startTime = v1;
      this.endTime = v2;
    }
  }
};
// 子组件时间段选择器代码
<template>
    <div class="timerChoose">
    	//这里通过绑定数组对象进行循环遍历的方式来创建各个时间点的块。因为选中状态和不选中状态的样式不一样,所以
    	//对他的class进行动态的绑定。
        <div class="timerItem" v-for="item in timerList" :key="item.id" :class="item.className"  @click="handClick(item)">
            {{item.text}}
        </div>
    </div>
</template>
<script>
export default {
	//这里接收来自父组件传递的数据
    props:{
        parentObj:{
            type:Object,
            default:'',
        }
    },
    data() {
        return {
       		//这里定义一个数组对象。
            timerList:[
                {
                    id:1,             //它的作用是用来记录块的下标
                    className:'',	  //他的作用是绑定动态的class名字。体现选中与不选中状态
                    text:'01:00'	  //时间块上显示的内容
                },
                {
                    id:2,
                    className:'',
                    text:'02:00'
                },
                {
                    id:3,
                    className:'',
                    text:'03:00'
                },
               ......//这里需要24个。剩余的省略。自行补充。
            ],
            clickNum:0,//记录点击的次数
            chooseList:[],//记录选取的时间段
            firstId:'',//记录第一次点击的ID
            lastId:'',//记录第二次点击的ID
            clickArr:[],//记录选中的块。并把他们的id存到该数组中
        }
    },
    created() {
      	//首先拿到父元素传递过来的数据。
        this.firstId = this.parentObj.startTime;
        this.lastId = this.parentObj.endTime;
    },
    mounted() {
    	//在mounted中执行显示默认时间的方法。注意这里不能再created中执行。因为created中dom并未被创建。
    	//所以无法为其动态绑定class
        this.showTimer();
    },
    methods: {
    	//默认显示时间
        showTimer(){
            let _this = this;
            //先定义一个空数组用来装父组件传递过来的时间段
            var newArr = [];
            /*
            	假如父组件此时传递的数据是:{startTime:05:00,endTime:18:00}
            	这里就要先将数据类型转化为整形。具体的转化方式网上很多。这里不再赘述。转完之后的数据为
            	{startTime:5,endTime:18}
            */
            //循环遍历父组件传递的时间点。将他们之间的时间都放在提前定义好的空数组newArr中。
            for(var i=this.firstId;i<=this.lastId+1;i++){
            	//5点到18点之间的时间点都作为数组的元素进行保存。
                newArr.push(i);
                //newArr=[5,6,7,8,9,10,11,12,13,14,15,16,17,18]
            }
            //循环遍历时间块的数组对象。
            this.timerList.forEach(element => {
            	//element就是每一个时间块
            	/*
            	...
            	{
            		id:2,
                    className:'',
                    text:'02:00'
            	}
            	...
            	*/
            	//在循环24个对象的内层对上边newArr进行循环。
                for(var j=0;j<newArr.length;j++){
                //将element中的id属性与父组件传过来的时间段进行对比。
                    if(element.id==newArr[j]){
                    //如果相同,就把时间块中的className重新进行赋值。定为选中状态。
                    /*
                    .active{
				        background: #2749F3;
				        color: #ffffff;
				    }
                    */
                        element.className = 'timerItem active';
                    }
                }      
            });
        }
        // 点击选择时间的方法
        handClick(e){
        //这是每个时间块的点击事件。e表示当前被点击的元素。可以拿到当前被点击元素的属性
            let _this=this;
            //首先进行点击次数的操作。第一次点击,当前被点击元素变为被选中状态。第二次点击,当前被点击元素与第一次被点击
            //元素之间的所有元素都变为被选中状态
            //首先判断点击次数是否为零
            if(this.clickNum==0){
            	//先把所有的选中状态清掉
                _this.timerList.forEach(element => {
                    element.className = 'timerItem';
                })
                //第一次被点击的元素className被变为选中状态
                e.className = 'timerItem active';
                //点击次数自加一次
                _this.clickNum++; 
                //记录第一次被点击的元素ID
                _this.firstId=e.id;         
            }else if(this.clickNum==1){//第二次被点击的情况
                e.className = 'timerItem active';//先把当前元素的状态改为选中状态
                var cid = '';//这里要进行一个数据的比对。要将小的一个时间点作为startTime。
                //所以需要将第一次点击的时间点与本次点击的时间点做对比
                if(e.id>_this.firstId){
                    _this.lastId=e.id;
                }else if(e.id<_this.firstId){
                    cid = _this.firstId;
                    _this.firstId = e.id;
                    _this.lastId = cid;
                }
                //将第一次点击的元素ID与第二次点击的元素ID之间的元素放到被点击元素的数组中,因为上面已经对
                //第一次点击和第二次点击的元素ID进行了比对和重新赋值,所以较小的在前。较大的一个在后。                
                for(var i = _this.firstId ; i<= _this.lastId; i++){
                    _this.clickArr.push(i);
                    /*
                    假设第一次点击的元素为04:00,第二次点击的元素为18:00,
                    那么这里的数组为clickArr=[4,5,6,7,8,9,10,11,12,13,14,15,16,,17,18]
                    */
                }
                //循环所有的时间块元素
                _this.timerList.forEach(element => {
                //循环点击两次之后,被放入点击点之间的元素数组
                    for(var j=0;j<=_this.clickArr.length;j++){
                    //进行比对。如果他们的ID相等
                        if(element.id == _this.clickArr[j]){
                        //就将元素标为被选中状态
                            element.className = 'timerItem active';
                        }
                    }  
                    //第二次点击之后要将点击次数清零
                    _this.clickNum=0;
                });  
                //将两次点击选中的时间点发送给父组件。由父组件执行下一步操作             
                this.$emit('childMsg', _this.firstId,_this.lastId+1)
                //两次点击过后将选中的元素数组清零
                _this.clickArr=[]; 
                //将记录第一次点击元素的ID和第二次点击元素的ID清空
                _this.lastId='';
                _this.firstId='';            
            }           
        },
    },
}
</script>
<style scoped>
    .timerChoose{
        width: 80%;
        height: 100%;
        display: flex;
        justify-content:space-around;
        flex-wrap: wrap;
    }
    .timerItem{
        width: 15%;
        height: 20%;
        background: #cccccc;
        text-align: center;
        display: flex;
        justify-content: space-around;
        flex-direction: column;
        font-size: 1rem;
        border-radius: 1rem;
    }
    .active{
        background: #2749F3;
        color: #ffffff;
    }
</style>

至此一天之间的时间段选择组件完成。一年之间的月分段组件与此相同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值