在Vant的基础上封装下拉日期控件的代码示例


Posted in Javascript onDecember 05, 2018

需求分析

在实际项目中,表单里面的日期选择是常用的组件。Vant有提供日期组件,但是居然没有提供下拉形式的日期组件,不过该有的元件都有,就自己封装一个。

封装组件过程中我们要解决:

  • 和表单的样式能兼容
  • 错误提示
  • 参数问题
  • 事件机制
  • 格式化

解决问题

就给新的组件取名为 VantFieldDate

期望使用的时候是这样的

<vant-field-date
 label="发布时间"
 v-model="formData.publishDate"
 type="datetime"
 :max-date="new Date()"
/>

具体实现,我贴上代码详细讲解。

<template>
 <div class="vant-field-date">
  <van-cell
   :title="label"
   :class="{'readonly': readonly, 'placeholder' : text}"
   :is-link="!readonly"
   :required="required"
   @click="show">
   <!-- 显示当前值,没有值显示提示文字 -->
   {{ text ? text : placeholder }}
   <!-- 自定义错误显示 -->
   <div
    v-if="$attrs.error"
    v-text="$attrs['error-message']"
    class="van-field__error-message"
   />
  </van-cell>
  <!-- 用 actionsheet 来包裹弹出层日期控件 -->
  <van-actionsheet v-model="isShowPicker">
   <!-- $attrs 可以把根节点的attr放到目标组件上,如此可以像使用 DatePicker 组件一样使用这个新组件 -->
   <van-datetime-picker
    v-bind="$attrs"
    :type="type"
    title="请选择日期"
    :min-date="minDate"
    :max-date="maxDate"
    @cancel="cancel"
    @confirm="confirm"
   />
  </van-actionsheet>
 </div>
</template>

<script>
 export default {
  name: 'VantFieldDate',
  inheritAttrs: false, // https://cn.vuejs.org/v2/api/#inheritAttrs
  props: {
   value: {
    type: [Number, Date],
    default: undefined // 值不能是 null,DatePicker会报错
   },
   // Cell 显示的文字
   label: {
    type: String,
    default: null
   },
   // 必填的星号
   required: {
    type: Boolean,
    default: false
   },
   // 只读状态
   readonly: {
    type: Boolean,
    default: false
   },
   // 占位提示文字
   placeholder: {
    type: String,
    default: '请选择'
   },
   // 展示的格式化
   format: {
    type: String,
    default: null
   }
  },
  data() {
   return {
    selectedItem: null,
    isShowPicker: false
   }
  },
  computed: {
   // 展示的格式化,时间提交的值是Date类型数据
   formatFormula() {
    if(this.format){
     return this.format
    } else if (this.type === 'date') {
     return 'yyyy-MM-dd'
    } else if (this.type === 'datetime') {
     return 'yyyy-MM-dd hh:mm'
    } else if (this.type === 'time') {
     return 'hh:mm'
    } else if (this.type === 'year-month') {
     return 'yyyy-MM'
    }
   },
   text() {
    return this.value ? this.dateFormat(this.value, this.formatFormula) : ''
   }
  },
  methods: {
   dateFormat: (value, format) => {
    if (!value) return
    if (!(value instanceof Date)) {
     value = new Date(value)
    }
    let o = {
     'M+': value.getMonth() + 1, // month
     'd+': value.getDate(), // day
     'h+': value.getHours(), // hour
     'm+': value.getMinutes(), // minute
     's+': value.getSeconds(), // second
     'q+': Math.floor((value.getMonth() + 3) / 3), // quarter
     'S': value.getMilliseconds() // millisecond
    }

    if (!format || format === '') {
     format = 'yyyy-MM-dd hh:mm:ss'
    }

    if (/(y+)/.test(format)) {
     format = format.replace(RegExp.$1, (value.getFullYear() + '').substr(4 - RegExp.$1.length))
    }

    for (let k in o) {
     if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length))
     }
    }
    return format
   },
   show() {
    if (!this.readonly) {
     this.isShowPicker = true
    }
   },
   confirm(value) {
    // 更新 v-model 绑定的 value 值,第二个参数是毫秒数,第三个参数是原始值,根据自己的项目的数据结构来修改
    // input 事件同时也会触发 vee-validate 的验证事件
    this.$emit('input', value.getTime(), value)
    // onChange事件,虽然重写 @input可以实现,但这样会破坏 v-model 写法。
    this.$emit('change', value.getTime(), value)
    this.cancel()
   },
   // 隐藏弹框
   cancel() {
    this.isShowPicker = false
   }
  }
 }
</script>

效果

在Vant的基础上封装下拉日期控件的代码示例

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

Javascript 相关文章推荐
jQuery.Validate 使用笔记(jQuery Validation范例 )
Jun 25 Javascript
jquery ajax 局部刷新小案例
Feb 08 Javascript
jquery阻止后续事件只执行第一个事件
Jul 24 Javascript
JavaScript实现继承的4种方法总结
Oct 16 Javascript
javascript通过获取html标签属性class实现多选项卡的方法
Jul 27 Javascript
jqPlot jQuery绘图插件的使用
Jun 18 Javascript
用自定义图片代替原生checkbox实现全选,删除以及提交的方法
Oct 18 Javascript
jquery 禁止鼠标右键并监听右键事件
Apr 27 jQuery
JS中的JSON对象的定义和取值实现代码
May 09 Javascript
react+ant design实现Table的增、删、改的示例代码
Dec 27 Javascript
vue ssr 实现方式(学习笔记)
Jan 18 Javascript
Vue3 中的数据侦测的实现
Oct 09 Javascript
Vant的安装和配合引入Vue.js项目里的方法步骤
Dec 05 #Javascript
微信小程序实现图片滚动效果示例
Dec 05 #Javascript
详解vue中的computed的this指向问题
Dec 05 #Javascript
使用rollup打包JS的方法步骤
Dec 05 #Javascript
微信小程序入门之广告条实现方法示例
Dec 05 #Javascript
Vue实现本地购物车功能
Dec 05 #Javascript
node和vue实现商城用户地址模块
Dec 05 #Javascript
You might like
我的论坛源代码(五)
2006/10/09 PHP
PHP中冒号、endif、endwhile、endfor使用介绍
2010/04/28 PHP
php正则表达式获取内容所有链接
2015/07/24 PHP
php中青蛙跳台阶的问题解决方法
2018/10/14 PHP
定位地理位置PHP判断员工打卡签到经纬度是否在打卡之内
2019/05/23 PHP
JavaScript isPrototypeOf和hasOwnProperty使用区别
2010/03/04 Javascript
正负小数点后两位浮点数实现原理及代码
2013/09/06 Javascript
JavaScript实现的一个计算数字步数的算法分享
2014/12/06 Javascript
js改变Iframe中Src的方法
2015/05/05 Javascript
node.js使用cluster实现多进程
2016/03/17 Javascript
node.js平台下利用cookie实现记住密码登陆(Express+Ejs+Mysql)
2017/04/26 Javascript
Vue.js实现分页查询功能
2020/11/15 Javascript
微信小程序收藏功能的实现代码
2018/06/12 Javascript
vue.js绑定事件监听器示例【基于v-on事件绑定】
2018/07/07 Javascript
jQuery实现表格隔行换色
2018/09/01 jQuery
Vue.js中 v-model 指令的修饰符详解
2018/12/03 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
2019/02/27 Javascript
使用post方法实现json往返传输数据的方法
2019/03/30 Javascript
JS利用prototype给类添加方法操作详解
2019/06/21 Javascript
JS实现简单的文字无缝上下滚动功能示例
2019/06/22 Javascript
JavaScript中window和document用法详解
2020/07/28 Javascript
解决vue刷新页面以后丢失store的数据问题
2020/08/11 Javascript
Ant design vue中的联动选择取消操作
2020/10/31 Javascript
python将ip地址转换成整数的方法
2015/03/17 Python
python操作MySQL 模拟简单银行转账操作
2017/09/27 Python
Windows下安装Scrapy
2018/10/17 Python
python中for循环输出列表索引与对应的值方法
2018/11/07 Python
Python自定义一个类实现字典dict功能的方法
2019/01/19 Python
Python项目 基于Scapy实现SYN泛洪攻击的方法
2019/07/23 Python
python list等分并从等分的子集中随机选取一个数
2020/11/16 Python
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
亚瑟士美国官网:ASICS美国
2017/02/01 全球购物
外贸专业求职信
2014/03/09 职场文书
创新社会管理心得体会
2014/09/12 职场文书
安全教育第一课观后感
2015/06/17 职场文书
教你如何使用Python开发一个钉钉群应答机器人
2021/06/21 Python