在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 相关文章推荐
HTML,CSS,JavaScript速查表推荐
Dec 02 Javascript
JavaScript使用pop方法移除数组最后一个元素用法实例
Apr 06 Javascript
JavaScript中的Repaint和Reflow用法详解
Jul 27 Javascript
jQuery与Ajax以及序列化
Feb 01 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
Sep 01 Javascript
JS简单去除数组中重复项的方法
Sep 13 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
Sep 17 Javascript
基于jQuery实现中英文切换导航条效果
Sep 18 Javascript
jQuery如何防止Ajax重复提交
Oct 14 Javascript
微信小程序之GET请求的实例详解
Sep 29 Javascript
使用vue-router切换页面时实现设置过渡动画
Oct 31 Javascript
JavaScript实现京东放大镜效果
Dec 03 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
封装一个PDO数据库操作类代码
2009/09/09 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
2013/06/14 PHP
PHP自定义错误用法示例
2016/09/28 PHP
效率高的Javscript字符串替换函数的benchmark
2008/08/02 Javascript
javascript 避免闭包引发的问题
2009/03/17 Javascript
js replace 与replaceall实例用法详解
2013/08/03 Javascript
JQuery动态添加和删除表格行的方法
2015/03/09 Javascript
json与jsonp知识小结(推荐)
2016/08/16 Javascript
快速实现jQuery多级菜单效果
2017/02/01 Javascript
vue数据双向绑定的注意点
2017/06/23 Javascript
Javascript中的作用域及块级作用域
2017/12/08 Javascript
Vue框架之goods组件开发详解
2018/01/25 Javascript
vue.js的computed,filter,get,set的用法及区别详解
2018/03/08 Javascript
微信开发之企业付款到银行卡接口开发的示例代码
2018/09/18 Javascript
NodeJS搭建HTTP服务器的实现步骤
2018/10/12 NodeJs
详解关于React-Router4.0跳转不置顶解决方案
2019/05/10 Javascript
layer.js open 隐藏滚动条的例子
2019/09/05 Javascript
JavaScript如何判断input数据类型
2020/02/06 Javascript
python检查序列seq是否含有aset中项的方法
2015/06/30 Python
浅析Python中yield关键词的作用与用法
2016/11/29 Python
python获取文件真实链接的方法,针对于302返回码
2018/05/14 Python
Selenium鼠标与键盘事件常用操作方法示例
2018/08/13 Python
详解python websocket获取实时数据的几种常见链接方式
2019/07/01 Python
pycharm不以pytest方式运行,想要切换回普通模式运行的操作
2020/09/01 Python
python 实现有道翻译功能
2021/02/26 Python
农林经济管理专业自荐信
2014/09/01 职场文书
建设幸福中国演讲稿
2014/09/11 职场文书
社区党风廉政建设调研报告
2015/01/01 职场文书
感恩节寄语2015
2015/03/24 职场文书
紧急通知
2015/04/17 职场文书
人民的好儿女观后感
2015/06/18 职场文书
2015年初中教师个人工作总结
2015/07/21 职场文书
师德师风心得体会(2016精选篇)
2016/01/12 职场文书
百善孝为先:关于孝道的经典语录
2019/10/18 职场文书
Win11 BitLocker 驱动器加密
2022/04/19 数码科技
在Windows Server 2012上安装 .NET Framework 3.5 所遇到的问题
2022/04/29 Servers