在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 相关文章推荐
ext监听事件方法[初级篇]
Apr 27 Javascript
jQuery 追加元素的方法如append、prepend、before
Jan 16 Javascript
jquery实现聚光灯效果的方法
Feb 06 Javascript
jquery中ajax跨域方法实例分析
Dec 18 Javascript
jQuery EasyUi 验证功能实例解析
Jan 06 Javascript
jQuery中on方法使用注意事项详解
Feb 15 Javascript
Angular.js去除页面中显示的空行方法示例
Mar 30 Javascript
利用js给datalist或select动态添加option选项的方法
Jan 25 Javascript
解决vue axios的封装 请求状态的错误提示问题
Sep 25 Javascript
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 jQuery
Vue核心概念Getter的使用方法
Jan 18 Javascript
JavaScript Dom 绑定事件操作实例详解
Oct 02 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如何编写易读的代码
2007/07/10 PHP
php中in_array函数用法分析
2014/11/15 PHP
PHP中使用xmlreader读取xml数据示例
2014/12/29 PHP
php简单实现无限分类树形列表的方法
2015/03/27 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
浅析PHP中的i++与++i的区别及效率
2016/06/15 PHP
PHP通过bypass disable functions执行系统命令的方法汇总
2018/05/02 PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
2019/05/13 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
js利用Array.splice实现Array的insert/remove
2009/01/13 Javascript
JavaScript检查某个function是否是原生代码的方法
2014/08/20 Javascript
js判断是否按下了Shift键的方法
2015/01/27 Javascript
JavaScript基于ajax编辑信息用法实例
2015/07/15 Javascript
jQuery基于ajax实现带动画效果无刷新柱状图投票代码
2015/08/10 Javascript
JS生成某个范围的随机数【四种情况详解】
2016/04/20 Javascript
Javascript中作用域的详细介绍
2016/10/06 Javascript
微信小程序支付前端源码
2018/08/29 Javascript
Vue使用JSEncrypt实现rsa加密及挂载方法
2020/02/07 Javascript
JS实现躲避粒子小游戏
2020/06/18 Javascript
python 切片和range()用法说明
2013/03/24 Python
python绘制铅球的运行轨迹代码分享
2017/11/14 Python
Python如何筛选序列中的元素的方法实现
2019/07/15 Python
Python同时迭代多个序列的方法
2020/07/28 Python
英国广泛的照明产品网站:Lights4living
2018/01/28 全球购物
专注澳大利亚特产和新西兰特产的澳洲中文网:0061澳洲制造
2019/03/24 全球购物
日本热销NO.1胶原蛋白冻:Aishitoto爱希特多
2019/06/20 全球购物
给物业的表扬信
2014/01/21 职场文书
大学毕业自我鉴定范文
2014/02/03 职场文书
《猴子种树》教学反思
2014/02/14 职场文书
服务之星事迹材料
2014/05/03 职场文书
中小学生学籍证明
2014/10/25 职场文书
项目转让协议书
2014/10/27 职场文书
暑期社会实践个人总结
2015/03/06 职场文书
保研导师推荐信
2015/03/25 职场文书
2016继续教育研修日志
2015/11/13 职场文书
剑指Offer之Java算法习题精讲二叉树专项训练
2022/03/21 Java/Android