基于Vant UI框架实现时间段选择器


Posted in Javascript onDecember 24, 2020

本文实例为大家分享了Vant UI框架实现时间段选择器的具体代码,供大家参考,具体内容如下

组件代码如下:

<template>
 <van-picker
   :title="title"
   :show-toolbar="showToolbar"
   :columns="columns"
   @confirm="onConfirm"
   @cancel="onCancel"
   @change="onChange"
   :confirm-button-text="confirmButtonText"
   :cancel-button-text="cancelButtonText"
   :loading="loading"
   :readonly="readonly"
   :item-height="itemHeight"
   :visible-item-count="visibleItemCount"
   :swipe-duration="swipeDuration"
 >
  <template slot="default">
   <slot name="default"></slot>
  </template>
  <template slot="title">
   <slot name="title"></slot>
  </template>
  <template slot="confirm">
   <slot name="confirm"></slot>
  </template>
  <template slot="cancel">
   <slot name="cancel"></slot>
  </template>
  <template slot="option">
   <slot name="option"></slot>
  </template>
  <template slot="columns-top">
   <slot name="columns-top"></slot>
  </template>
  <template slot="columns-bottom">
   <slot name="columns-bottom"></slot>
  </template>
 </van-picker>
</template>

<script>
 import Vue from 'vue'
 import { Field, Picker, Popup } from 'vant';
 Vue.use(Field).use(Picker).use(Popup);

 export default {
  name: "VanDatePicker",
  props: {
   value: {
    type: Date,
    default: () => new Date()
   },
   minDate: {
    type: Date,
    default: () => new Date(new Date().getFullYear()-5,0,1)
   },
   maxDate: {
    type: Date,
    default: () => new Date(new Date().getFullYear()+5,0,1)
   },
   showToolbar: {
    type: Boolean,
    default: () => false
   },
   title: {
    type: String,
    default: () => ''
   },
   confirmButtonText: {
    type: String,
    default: () => '确认'
   },
   cancelButtonText: {
    type: String,
    default: () => '取消'
   },
   loading: {
    type: Boolean,
    default: () => false
   },
   readonly: {
    type: Boolean,
    default: () => false
   },
   itemHeight: {
    type: Number||String,
    default: () => 44
   },
   visibleItemCount: {
    type: Number||String,
    default: () => 6
   },
   swipeDuration: {
    type: Number||String,
    default: () => 1000
   },
  },
  data() {
   return {
    monthArr: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'],
    dayArr: ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12','13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24','25', '26', '27', '28', '29', '30', '31'],
   };
  },
  
  computed: {
   columns: function () {
    let minYear = this.minDate.getFullYear();
    let maxYear = this.maxDate.getFullYear();
    let year = this.value.getFullYear();
    let month = this.value.getMonth();
    let day = this.value.getDate();
    let yearArr = [];
    let i = 0;
    while (i < maxYear - minYear + 1) {
     yearArr.unshift((maxYear - i) + '');
     i ++;
    }
    let columns = [
     {
      values: yearArr,
      defaultIndex: Math.floor(year) - minYear
     },
     {
      values: this.monthArr,
      defaultIndex: Math.floor(month)
     },
     {
      values: this.dayArr,
      defaultIndex: Math.floor(day-1)
     },
     {
      values: ['-']
     },
     {
      values: yearArr,
      defaultIndex: Math.floor(year) - minYear
     },
     {
      values: this.monthArr,
      defaultIndex: Math.floor(month)
     },
     {
      values: this.dayArr,
      defaultIndex: Math.floor(day-1)
     },
    ];
    return columns
   }
  },

  watch: {

  },
  
  methods: {
   onConfirm(value, index) {
    // console.log(`当前值:${value}, 当前索引:${index}`);
    this.$emit('confirm',value,index);
   },
   onChange(picker, value, index) {
    // console.log(`当前值:${value}, 当前索引:${index}`);
    let _this = this;

    let minMonth = this.minDate.getMonth();
    let minDay = this.minDate.getDate();
    let maxMonth = this.maxDate.getMonth();
    let maxDay = this.maxDate.getDate();
    let d = new Date(value[0],value[1],0);

    setDate(0);
    setDate(4);
    function setDate(i) {
     //最小年份
     if (value[i]-0===_this.minDate.getFullYear()) {
      picker.setColumnValues(i+1,_this.monthArr.slice(minMonth));
      let strMinM = '';
      if (minMonth<9) {
       strMinM = '0'+(minMonth+1)
      } else {
       strMinM = strMinM + 1 + ''
      }
      picker.setColumnValue(i+1,value[i+1]-1<minMonth?strMinM:value[i+1]);

      if (index===i&&value[i+1]-1<minMonth) {
       picker.setColumnValues(i+2,_this.dayArr.slice(minDay-1,d.getDate()));
       picker.setColumnValue(i+2,value[i+2]<minDay?minDay.toString():value[i+2]);
      } else {
       if (value[i+1]-1===_this.minDate.getMonth()) {
        picker.setColumnValues(i+2,_this.dayArr.slice(minDay-1,d.getDate()));
        picker.setColumnValue(i+2,value[i+2]<minDay?minDay.toString():value[i+2]);
       } else {
        picker.setColumnValues(i+2,_this.dayArr.slice(0,d.getDate()));
        picker.setColumnValue(i+2,value[i+2]>d.getDate()?d.getDate().toString():value[i+2]);
       }
      }
     }
     //最大年份
     else if (value[i]-0===_this.maxDate.getFullYear()) {
      picker.setColumnValues(i+1,_this.monthArr.slice(0,maxMonth+1));
      let strManM = '';
      if (maxMonth<9) {
       strManM = '0'+(maxMonth+1)
      } else {
       strManM = maxMonth + 1 + ''
      }
      picker.setColumnValue(i+1,value[i+1]-1>maxMonth?strManM:value[i+1]);
      if (index===i&&value[i+1]-1>maxMonth) {
       picker.setColumnValues(i+2,_this.dayArr.slice(0,maxDay));
       picker.setColumnValue(i+2,value[i+2]>maxDay?maxDay.toString():value[i+2]);
      } else {
       if (value[i+1]-1===_this.maxDate.getMonth()) {
        picker.setColumnValues(i+2,_this.dayArr.slice(0,maxDay));
        picker.setColumnValue(i+2,value[i+2]>maxDay?maxDay.toString():value[i+2]);
       } else {
        picker.setColumnValues(i+2,_this.dayArr.slice(0,d.getDate()));
        picker.setColumnValue(i+2,value[i+2]>d.getDate()?d.getDate().toString():value[i+2]);
       }
      }
     }
     //其他年份
     else {
      picker.setColumnValues(i+1,_this.monthArr);
      picker.setColumnValue(i+1,value[i+1]);
      picker.setColumnValues(i+2,_this.dayArr.slice(0,d.getDate()));
      picker.setColumnValue(i+2,value[i+2]>d.getDate()?d.getDate().toString():value[i+2]);
     }
    }

    let finallyVal = picker.getValues();
    let len = Math.floor(finallyVal.length/2);
    //开始时间不大于结束时间
    if (finallyVal.slice(0,len).join("")>finallyVal.slice(len+1).join("")){
     picker.setValues([...finallyVal.slice(0,len),"-",...finallyVal.slice(0,len)]);
     if (new Date(finallyVal.slice(0,len).join("-")+' 00:00:00').getTime()===this.maxDate.getTime()) {
      console.log(111);
      picker.setColumnValues(5,_this.monthArr.slice(0,maxMonth+1));
      picker.setColumnValues(6,_this.dayArr.slice(0,maxDay));
     }
    }

    this.$emit('change',picker,finallyVal,index);
   },
   onCancel() {
    // console.log('取消');
    this.$emit('cancel');
   },
  },
 }
</script>

<style scoped>

</style>

调用demo

<template>
 <div>
  <van-field
    readonly
    clickable
    label="时间段"
    :value="value"
    placeholder="选择时间段"
    @click="showPicker = true"
  />
  <van-popup v-model="showPicker" round position="bottom">
   <van-date-picker
     show-toolbar
     v-model="currentDate"
  title="选择时间段"
     :min-date="minDate"
     :max-date="maxDate"
     @cancel="showPicker = false"
     @confirm="onConfirm"
     @change="onChange"
   >
   </van-date-picker>
  </van-popup>
 </div>
</template>

<script>
 import VanDatePicker from '@/components/VanDatePicker';

 export default {
  name: "Test",
  components: {VanDatePicker},
  data() {
   return {
    value: '',
    showPicker: false,
    minDate: new Date(2010, 5, 15),
    maxDate: new Date(2025, 10, 15),
    currentDate: new Date(),
    startDate: '',
    endDate: '',
   };
  },

  mounted() {

  },

  methods: {
   onConfirm(value, index) {
    console.log(`当前值:${value}, 当前索引:${index}`);
    this.startDate = value.slice(0,3).join('-');
    this.endDate = value.slice(4,7).join('-');
    this.value = this.startDate + '至' + this.endDate;
    this.showPicker = false
   },

   onChange(picker, value, index) {
    console.log(`当前值:${value}, 当前索引:${index}`);
   },
  },
 }
</script>

<style scoped>

</style>

UI示例

基于Vant UI框架实现时间段选择器

API:注意红色划掉的没有实现

基于Vant UI框架实现时间段选择器

基于Vant UI框架实现时间段选择器

基于Vant UI框架实现时间段选择器

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 嵌套的函数(作用域链)
Mar 15 Javascript
JavaScript获取Url里的参数
Dec 18 Javascript
原生javascript实现图片滚动、延时加载功能
Jan 12 Javascript
js实现div拖动动画运行轨迹效果代码分享
Aug 27 Javascript
详解Javascript事件驱动编程
Jan 03 Javascript
7个去伪存真的JavaScript面试题
Jan 07 Javascript
基于vue的fullpage.js单页滚动插件
Mar 20 Javascript
微信小程序踩坑记录之解决tabBar.list[3].selectedIconPath大小超过40kb
Jul 04 Javascript
vue中的ref和$refs的使用
Nov 22 Javascript
Vue+Express实现登录注销功能的实例代码
May 05 Javascript
JavaScript监听触摸事件代码实例
Dec 30 Javascript
用webAPI实现图片放大镜效果
Nov 23 Javascript
原生jQuery实现只显示年份下拉框
Dec 24 #jQuery
js制作提示框插件
Dec 24 #Javascript
vue+openlayers绘制省市边界线
Dec 24 #Vue.js
在HTML中使用JavaScript的两种方法
Dec 24 #Javascript
vue项目中openlayers绘制行政区划
Dec 24 #Vue.js
Vue+penlayers实现多边形绘制及展示
Dec 24 #Vue.js
Vue使用鼠标在Canvas上绘制矩形
Dec 24 #Vue.js
You might like
Thinkphp模板标签if和eq的区别和比较实例分析
2015/07/01 PHP
使用PHP json_decode可能遇到的坑与解决方法
2017/08/03 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
javascript 火狐(firefox)不显示本地图片问题解决
2008/07/05 Javascript
Jquery实现页面加载时弹出对话框代码
2013/04/19 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
2014/06/01 Javascript
JavaScript和CSS交互的方法汇总
2014/12/02 Javascript
使用AngularJS中的SCE来防止XSS攻击的方法
2015/06/18 Javascript
使用jquery给指定的table动态添加一行、删除一行
2016/10/13 Javascript
AngularJs表单验证实例代码解析
2016/11/29 Javascript
js实现canvas保存图片为png格式并下载到本地的方法
2017/08/31 Javascript
轻松搞定jQuery+JSONP跨域请求的解决方案
2018/03/06 jQuery
vue轮播图插件vue-concise-slider的使用
2018/03/13 Javascript
浅谈JS对象添加getter与setter的5种方法
2018/06/09 Javascript
小程序云开发如何实现图片上传及发表文字
2019/05/17 Javascript
Vue element-ui父组件控制子组件的表单校验操作
2020/07/17 Javascript
Webpack5正式发布,有哪些新特性
2020/10/12 Javascript
vue+openlayers绘制省市边界线
2020/12/24 Vue.js
python ElementTree 基本读操作示例
2009/04/09 Python
Python SQLite3数据库操作类分享
2014/06/10 Python
Python爬取Coursera课程资源的详细过程
2014/11/04 Python
Python 记录日志的灵活性和可配置性介绍
2018/02/27 Python
Python中 map()函数的用法详解
2018/07/10 Python
python实现杨辉三角的几种方法代码实例
2021/03/02 Python
详解CSS3 Media Queries中媒体属性的使用
2016/02/29 HTML / CSS
澳大利亚最受欢迎的美发和美容在线商店:Catwalk
2018/12/12 全球购物
英国国家美术馆商店:National Gallery
2019/05/01 全球购物
.NET方向面试题
2014/11/20 面试题
中间件分为哪几类
2016/09/18 面试题
考试不及格的检讨书
2014/01/22 职场文书
幼儿园运动会入场词
2014/02/10 职场文书
个人工作主要事迹
2014/05/08 职场文书
土地租赁意向书
2014/07/30 职场文书
王金山在党的群众路线教育实践活动总结大会上的讲话稿
2014/10/25 职场文书
2016优秀护士先进个人事迹材料
2016/02/25 职场文书