在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 相关文章推荐
JQuery 绑定select标签的onchange事件,弹出选择的值,并实现跳转、传参
Jan 06 Javascript
在jQuery ajax中按钮button和submit的区别分析
Oct 07 Javascript
脚本合并提升javascript性能示例
Feb 24 Javascript
javascript将相对路径转绝对路径示例
Mar 14 Javascript
整理Javascript基础入门学习笔记
Nov 29 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
Jan 10 Javascript
JS自动生成动态HTML验证码页面
Jun 14 Javascript
深入理解Angular4订阅(Subscribe)与取消
Nov 22 Javascript
在vue中使用Autoprefixed的方法
Jul 27 Javascript
vue动态注册组件实例代码详解
May 30 Javascript
通过angular CDK实现页面元素拖放的步骤详解
Jul 01 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实现首页链接查询 友情链接检查的代码
2010/01/05 PHP
php ZipArchive压缩函数详解实例
2013/11/06 PHP
解决php接收shell返回的结果中文乱码问题
2014/01/23 PHP
2个Codeigniter文件批量上传控制器写法例子
2014/07/25 PHP
PHP使用Session遇到的一个Permission denied Notice解决办法
2014/07/30 PHP
CI框架封装的常用图像处理方法(缩略图,水印,旋转,上传等)
2016/11/22 PHP
PHP文件类型检查及fileinfo模块安装使用详解
2019/05/09 PHP
PHP isset()及empty()用法区别详解
2020/08/29 PHP
Jquery升级新版本后选择器的语法问题
2010/06/02 Javascript
jQuery Select(单选) 模拟插件 V1.3.62 改进版
2010/07/17 Javascript
JQuery的$命名冲突详细解析
2013/12/28 Javascript
BootStrap创建响应式导航条实例代码
2016/05/31 Javascript
WEB 前端开发中防治重复提交的实现方法
2016/10/26 Javascript
一道面试题引发的对javascript类型转换的思考
2017/03/06 Javascript
小程序实现左右来回滚动字幕效果
2018/12/28 Javascript
微信小程序实现日期格式化和倒计时
2020/11/01 Javascript
node.js基于dgram数据报模块创建UDP服务器和客户端操作示例
2020/02/12 Javascript
Vue如何跨组件传递Slot的实现
2020/12/14 Vue.js
对pandas写入读取h5文件的方法详解
2018/12/28 Python
python高斯分布概率密度函数的使用详解
2019/07/10 Python
python 并发编程 多路复用IO模型详解
2019/08/20 Python
几款Python编译器比较与推荐(小结)
2020/10/15 Python
python 多线程爬取壁纸网站的示例
2021/02/20 Python
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
英语商务邀请函范文
2014/01/16 职场文书
2014年女职工工作总结
2014/11/27 职场文书
高一军训决心书
2015/02/05 职场文书
感恩母亲节活动总结
2015/02/10 职场文书
2015年办公室主任工作总结
2015/04/09 职场文书
法院答辩状格式
2015/05/22 职场文书
银行资信证明
2015/06/17 职场文书
钢铁是怎样炼成的读书笔记
2015/06/29 职场文书
搞笑的婚礼主持词
2015/06/29 职场文书
2016年情人节广告语
2016/01/28 职场文书
争做文明公民倡议书
2019/06/24 职场文书
python 实现的截屏工具
2021/05/08 Python