利用vue-awesome-picker模仿支付宝做的一个时间控件

3 篇文章 0 订阅

 

vue-awesome-picker 做时间控件的时候 好像只有点确定 才可以返回值  滑动时间的时候好像没有事件可以调用于是把他的源码直接拿过来用一下

做成组件形式

<template>
    <div class="ed_body">
          <div class="ed_top">
              <strong>选择时间</strong>
              <span class="sp_1" @click="cancel">取消</span>
              <span class="sp_2" @click="accomplish">完成</span>
              <i class="g_hx"></i>
          </div>

          <div :class="selectDate?'ed_date ed_date2':'ed_date'">{{selectDate || '选择月份'}} <i class="iconfont icon-shanchu" @click="deleteDate"></i></div>
           
           
           
           <!-- 时期插件 开始时间  -->
          <awesome-date ref="picker" :anchor="picker0.anchor" :data="picker0.data" :colorCancel="colorCancel" :colorConfirm="colorConfirm" @scrollUpdateData="scrollUpdateData" @confirm="handlePicker0Confirm"></awesome-date>
  
 
    </div>
</template>

<script>
    import awesomeDate from "../../components/awesome-date/awesome-date";
    export default {
        name: "earningsDate",
        data(){
          return {
            isPickerYear:false,  //是否显示年份的picker
            picker0:{
              anchor:[],
              data:[]
              //data:[]
            },
            colorConfirm:"#007AFF",  //picker控件 确认的颜色
            colorCancel:"#0D0C0C",  //picker控件 取消的颜色
            lineWidth:15,  //下面那个导航条有多少宽  单位px
            swipeThreshold:6, //导向切换 有几个就可以滑动

            selectDate:"",  //选择的时间
            currentMonth:0, //当前月份
            oldIndex:-1,  //第一竖之前的索引 用来记录上一次的索引 
          }
        },
      components:{
          "awesome-date":awesomeDate
      },
        mounted() { 
          this.initData();
          this.openPicker();
        },
      methods:{ 
      	initData(){
      	  let y = []; //年
      	  let d = [];  //月
          let currentMonth = new Date().getMonth() - 0 +1;
          this.currentMonth = currentMonth;
      	  let date = new Date().getFullYear();
      	  for(let i = 0; i < 10; i++){
      	     y.push(date+"年");
      	     date --;
          }
      	  for(let i = currentMonth; i > 0; i--){
      	     d.push(i+"月");
          }
          this.picker0.data.push(y);
          this.picker0.data.push(d);
      	},
        //选择年份
        handlePicker0Confirm(v){

        },
        openPicker(){
          this.$refs.picker.show();
        },
        //滚动选择后的回调
        scrollUpdateData(v){
          let y = v[0].value.toString().replace("年","-");
          let m = v[1].value.toString().replace("月","");
          if(m < 10){
             m = "0"+m;
          }
      	  this.selectDate = y + m  ;
      	  let firstIndex = v[0].index; //第一个索引
      	  let oldIndex = this.oldIndex;
      	  let d = [];  //月
      	  if(firstIndex == 0){ //表示是本月
      	  	   for(let i = this.currentMonth; i > 0; i--){
	      	     d.push(i+"月");
	           }
      	  }else{
      	  	   for(let i = 12; i > 0; i--){
	      	     d.push(i+"月");
	           }
      	  }
      	  this.oldIndex = firstIndex;
      	  if(firstIndex != oldIndex){ //只有第一排这次的索引跟上次的索引不一样时 才引起后面月份的变化 不然不变
      	  	  this.$refs.picker._reloadWheel(1,d);
      	  }
          console.log(JSON.stringify(v))
        },
        //完成
        accomplish(){
      	   this.$emit("accomplish",this.selectDate);
        },
        //删除
        deleteDate(){
          this.$emit("accomplish",false);
        },
        //取消
        cancel(){
          this.$emit("cancel",false);
        }
      }

    }
</script>

<style lang="scss" scoped>
  @import "../../style/mixin";
    .ed_body{
        position: fixed;
        width: 100%;
        height: 100%;
       background: #FFFFFF;
        left: 0;
        top: 0;
        z-index: 1000000;
      animation-name: ed_body;
      animation-duration: 0.5s;
      animation-delay: 0s;
      animation-iteration-count: 1;
      animation-direction: normal;
    }
  .ed_top{
     position: relative;
      width: 100%;
      height: 1.3rem;
      strong{
        float: left;
        width: 100%;
        height: 1.3rem;
        line-height: 1.7rem;
        text-align: center;
        @include sc(0.34rem,#000000);
      }
      span{
        position: absolute;
        height: 1.3rem;
        line-height: 1.7rem;
        top: 0;
        @include sc(0.34rem,#007AFF);
        padding: 0 0.4rem;
      }
     .sp_1{
       left: 0;
     }
    .sp_2{
      right: 0;
    }
    .g_hx{
      position: absolute;
      width: 100%;
      border-bottom: #CDCED3 solid 1px;
      left: 0;
      bottom: 1px;
    }
  }

  .ed_date{
    position: relative;
    width: 6.7rem;
    height: 0.88rem;
    line-height: 0.88rem;
    margin:1.5rem auto 0;
    border-bottom: #CDCED3 solid 2px;
    @include sc(0.34rem,#BBBBBB);  
    text-align: center;
    i{   
      position: absolute;
      width: 0.36rem;
      height: 0.4rem;
      @include sc(0.36rem,#0D0D0D);
      right: 0;
      bottom: -0.68rem;
      z-index: 100000;
    }
  }
  .ed_date2{
  	 color:#007AFF;
  }
  
  .mask{
  	 display: none;
  }
  .picker-title{
  	 display: none;
  }

  @keyframes ed_body {
    0% {
      top: 110%;
    }
    100% {
      top: 0;
    }
  }
</style>

其中import awesomeDate from "../../components/awesome-date/awesome-date"; 是直接用的vue-awesome-picker的源码

对awesome-date源码进行分析的时候发现

_createWheel (wheelWrapper, i) {
  if (!this.wheels[i]) {
    const wheel = this.wheels[i] = new BScroll(wheelWrapper.children[i], {
      wheel: {
        selectedIndex: 0,
        rotate: 25
      },
      swipeTime: this.swipeTime
    })
    wheel.on('scrollEnd', () => {
      this._cascadePickerChange(i)
    })
  } else {
    this.wheels[i].refresh()
  }
  return this.wheels[i]
},

每次createWheel的时候 wheel.on 绑定了一个 scrollEnd 方法 this._cascadePickerChange(i)

找到_cascadePickerChange方法添加

let currentData = this._getCurrentValue(); 
this.$emit("scrollUpdateData", currentData);

这样就可以得到所选择的日期的值了 又因为我是选择一个一个年 再重新给月份赋值(发现官网的级联有问题 只有最开始赋值就没问题 在data()里面赋值就没问题,后面动态赋的值有问题 所以就选择一个年赋一会月的值) 所以得到的月份一直都停留在之前的值,所以要在每次改变值的时候拿到默认(第一个)月份的值

再分析源码 每次有值改变的时候 都会调用_reloadWheel方法 之前原有的代码不变加上自己需要的代码

所以

_reloadWheel (index, data) {
        const wheelWrapper = this.$refs.wheelWrapper
        let scroll = wheelWrapper.children[index].querySelector('.wheel-scroll')
        let wheel = this.wheels ? this.wheels[index] : false
        let dist = 0
        if (scroll && wheel) {
          this.$set(this.pickerData, index, data)
          this.pickerAnchor[index] = dist
          this.$nextTick(() => {
            wheel = this._createWheel(wheelWrapper, index)
            wheel.wheelTo(dist)
          })
        }
        let currentData = this._getCurrentValue();
        this.$emit("scrollUpdateData", currentData);
        return dist
      },

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值