在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 相关文章推荐
【消息提示组件】,兼容IE6/7&amp;&amp;FF2
Sep 04 Javascript
Jquery数独游戏解析(一)-页面布局
Nov 05 Javascript
jQuery-onload让第一次页面加载时图片是淡入方式显示
May 23 Javascript
如何使Chrome控制台支持多行js模式——意外发现
Jun 13 Javascript
Jquery ajaxStart()与ajaxStop()方法(实例讲解)
Dec 18 Javascript
ff chrome和ie下全局动态定位的异同及全局高度的取法
Jun 30 Javascript
Bootstrap 3.x打印预览背景色与文字显示异常的解决
Nov 06 Javascript
浅谈jQuery before和insertBefore的区别
Dec 04 Javascript
jQuery条件分页 代替离线查询(附代码)
Aug 17 jQuery
JavaScript中使用Spread运算符的八种方法总结
Jun 18 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
Aug 30 Javascript
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
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
在PHP中养成7个面向对象的好习惯
2010/01/28 PHP
PHP的可变变量名的使用方法分享
2012/02/05 PHP
详解PHP内置访问资源的超时时间 time_out file_get_contents read_file
2013/06/03 PHP
php中require和require_once的区别说明
2014/02/27 PHP
PHP基于接口技术实现简单的多态应用完整实例
2017/04/26 PHP
PHP中遍历数组的三种常用方法实例分析
2019/06/24 PHP
使用composer安装使用thinkphp6.0框架问题【视频教程】
2019/10/01 PHP
js 编程笔记 无名函数
2011/06/28 Javascript
javascript中日期转换成时间戳的小例子
2013/03/21 Javascript
js动态创建、删除表格示例代码
2013/08/07 Javascript
JavaScript利用正则表达式去除日期中的“-”
2014/07/01 Javascript
jquery.form.js实现将form提交转为ajax方式提交的方法
2015/04/07 Javascript
jQuery简单tab切换效果实现方法
2015/04/08 Javascript
Bootstrap插件全集
2016/07/18 Javascript
js实现简单的计算器功能
2017/01/16 Javascript
Ajax验证用户名或昵称是否已被注册
2017/04/05 Javascript
使用OPENLAYERS3实现点选的方法
2020/09/24 Javascript
想用好React的你必须要知道的一些事情
2017/07/24 Javascript
详解vue-cli 快速搭建单页应用之遇到的问题及解决办法
2018/03/01 Javascript
Vue自定义全局Toast和Loading的实例详解
2019/04/18 Javascript
ES6 十大特性简介
2020/12/09 Javascript
element 动态合并表格的步骤
2020/12/31 Javascript
[00:44]华丽开场!DOTA2勇士令状带来全新对阵画面
2019/05/15 DOTA
深度定制Python的Flask框架开发环境的一些技巧总结
2016/07/12 Python
Python编程之字符串模板(Template)用法实例分析
2017/07/22 Python
对Python之gzip文件读写的方法详解
2019/02/08 Python
对PyQt5的输入对话框使用(QInputDialog)详解
2019/06/25 Python
python调用接口的4种方式代码实例
2019/11/19 Python
CSS3 text-shadow实现文字阴影效果
2016/02/24 HTML / CSS
Html5插件教程之添加浏览器放大镜效果的商品橱窗
2016/01/07 HTML / CSS
建筑文秘专业个人求职信范文
2013/12/28 职场文书
食品工程专业求职信
2014/06/15 职场文书
新生开学寄语大全
2015/05/28 职场文书
爱护公物主题班会
2015/08/17 职场文书
2015年幼儿园班主任个人工作总结
2015/10/22 职场文书
导游词之贵州织金洞
2019/10/12 职场文书