在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 相关文章推荐
关于文本限制字数的js代码
Apr 02 Javascript
让innerText在firefox火狐和IE浏览器都能用的写法
May 14 Javascript
jQuery手机浏览器中拖拽动作的艰难性分析
Feb 04 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
Oct 10 Javascript
快速掌握Node.js事件驱动模型
Mar 21 Javascript
Angularjs---项目搭建图文教程
Jul 08 Javascript
AngularJS控制器详解及示例代码
Aug 16 Javascript
JavaScript实现公历转农历功能示例
Feb 13 Javascript
JS排序之快速排序详解
Apr 08 Javascript
在knockoutjs 上自己实现的flux(实例讲解)
Dec 18 Javascript
微信小程序自定义轮播图
Nov 04 Javascript
JavaScript动画实例之粒子文本的实现方法详解
Jul 28 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
php 图像函数大举例(非原创)
2009/06/20 PHP
php自动注册登录验证机制实现代码
2011/12/20 PHP
php类中的各种拦截器用法分析
2014/11/03 PHP
php开发时容易忘记的一些技术细节
2016/02/03 PHP
php封装一个异常的处理类
2017/06/08 PHP
PHP实现压缩图片尺寸并转为jpg格式的方法示例
2018/05/10 PHP
javascript的trim,ltrim,rtrim自定义函数
2008/09/21 Javascript
JavaScript 验证浏览器是否支持javascript的方法小结
2009/05/17 Javascript
JSQL 批量图片切换的实现代码
2010/05/05 Javascript
如何确保JavaScript的执行顺序 之jQuery.html并非万能钥匙
2011/03/03 Javascript
通过action传过来的值在option获取进行验证的方法
2013/11/14 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
2017/01/22 Javascript
Webpack+Vue如何导入Jquery和Jquery的第三方插件
2017/02/20 Javascript
jQuery插件Echarts实现的渐变色柱状图
2017/03/23 jQuery
vue 表单验证按钮事件交由父组件触发的方法
2018/12/17 Javascript
详解如何搭建mpvue框架搭配vant组件库的小程序项目
2019/05/16 Javascript
[01:07:15]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第二场 1月25日
2021/03/11 DOTA
利用Python操作消息队列RabbitMQ的方法教程
2017/07/19 Python
python实现决策树
2017/12/21 Python
Python+matplotlib+numpy绘制精美的条形统计图
2018/01/02 Python
python3+selenium自动化测试框架详解
2019/03/17 Python
python实现视频分帧效果
2019/05/31 Python
美国在线鲜花速递:ProFlowers
2017/01/05 全球购物
英国山地公路自行车商店:Tweeks Cycles
2018/03/16 全球购物
财务出纳员岗位职责
2013/11/26 职场文书
《大江保卫战》教学反思
2014/04/11 职场文书
我的小天地教学反思
2014/04/30 职场文书
关于热爱祖国的演讲稿
2014/05/04 职场文书
公司股东出资证明书
2014/11/01 职场文书
惊天动地观后感
2015/06/10 职场文书
MongoDB balancer的使用详解
2021/04/30 MongoDB
利用Selenium添加cookie实现自动登录的示例代码(fofa)
2021/05/08 Python
python随机打印成绩排名表
2021/06/23 Python
SpringBoot整合JWT的入门指南
2021/06/29 Java/Android
2022年四月新番
2022/03/15 日漫
详细聊一聊mysql的树形结构存储以及查询
2022/04/05 MySQL