在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 相关文章推荐
JavaScript实现页面滚动图片加载(仿lazyload效果)
Jul 22 Javascript
无闪烁更新网页内容JS实现
Dec 19 Javascript
利用JavaScript检测CPU使用率自己写的
Mar 22 Javascript
Javascript学习笔记之 对象篇(三) : hasOwnProperty
Jun 24 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
Mar 23 Javascript
纯JS实现只能输入数字的简单代码
Jun 21 Javascript
提高Node.js性能的应用技巧分享
Aug 10 Javascript
利用Javascript开发一个二维周视图日历
Dec 14 Javascript
JavaScript同源策略和跨域访问实例详解
Apr 03 Javascript
Windows下Node爬虫神器Puppeteer安装记
Jan 09 Javascript
Vue proxyTable配置多个接口地址,解决跨域的问题
Sep 11 Javascript
JavaScript对象访问器Getter及Setter原理解析
Dec 08 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
DOTA2【瓜皮时刻】Vol.91 RTZ山史最惨“矿难”
2021/03/05 DOTA
不用GD库生成当前时间的PNG格式图象的程序
2006/10/09 PHP
PHP中list()函数用法实例简析
2016/01/08 PHP
Yii2.0 模态弹出框+ajax提交表单
2016/05/22 PHP
thinkPHP5.0框架验证码调用及点击图片刷新简单实现方法
2018/09/07 PHP
php远程请求CURL实例教程(爬虫、保存登录状态)
2020/12/10 PHP
js multiple全选与取消全选实现代码
2012/12/04 Javascript
使用按钮控制以何种方式打开新窗口的属性介绍
2012/12/17 Javascript
多个jquery.datatable共存,checkbox全选异常的快速解决方法
2013/12/10 Javascript
node.js中的fs.rmdir方法使用说明
2014/12/16 Javascript
JavaScript中的bold()方法使用详解
2015/06/08 Javascript
AngularJS Controller作用域
2017/01/09 Javascript
jQuery Ajax使用FormData上传文件和其他数据后端web.py获取
2017/06/11 jQuery
easyui下拉框动态级联加载的示例代码
2017/11/29 Javascript
基于jquery的on和click的区别详解
2018/01/15 jQuery
nodejs爬虫初试superagent和cheerio
2018/03/05 NodeJs
基于vue-element组件实现音乐播放器功能
2018/05/06 Javascript
JS遍历JSON数组及获取JSON数组长度操作示例【测试可用】
2018/12/12 Javascript
vue中的v-model原理,与组件自定义v-model详解
2020/08/04 Javascript
[01:09]DOTA2次级职业联赛 - ishow.HMM战队宣传片
2014/12/01 DOTA
Python中dict和set的用法讲解
2019/03/28 Python
基于python3 pyQt5 QtDesignner实现窗口化猜数字游戏功能
2019/07/15 Python
python如何将多个PDF进行合并
2019/08/13 Python
Python容器使用的5个技巧和2个误区总结
2019/09/26 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
Django中如何用xlwt生成表格的方法步骤
2021/01/31 Python
美国顶级奢侈茶:Mighty Leaf Tea(美泰茶)
2016/11/26 全球购物
巴西箱包、背包、钱包和旅行配件购物网站:Inovathi
2019/12/14 全球购物
党章培训心得体会
2014/09/04 职场文书
纪念9.18事变演讲稿
2014/09/14 职场文书
客房部经理岗位职责
2015/02/02 职场文书
幼儿园六一儿童节活动总结
2015/02/10 职场文书
2015年中秋节活动总结
2015/03/23 职场文书
2015年质检工作总结
2015/05/04 职场文书
尼克胡哲观后感
2015/06/08 职场文书
高中议论文(范文2篇)
2019/08/19 职场文书