在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实现下拉菜单效果的代码
Jul 25 Javascript
图片动画横条广告带上下滚动的JS代码
Oct 25 Javascript
深入分析JQuery和JavaScript的异同
Oct 23 Javascript
Validform+layer实现漂亮的表单验证特效
Jan 17 Javascript
JavaScript判断表单为空及获取焦点的方法
Feb 12 Javascript
基于JS代码实现实时显示系统时间
Jun 16 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
Dec 08 Javascript
通过vue-cli来学习修改Webpack多环境配置和发布问题
Dec 22 Javascript
详解VUE Element-UI多级菜单动态渲染的组件
Apr 25 Javascript
JS实现点击生成UUID的方法完整实例【基于jQuery】
Jun 12 jQuery
vue实现路由监听和参数监听
Oct 29 Javascript
分享JS表单验证源码(带错误提示及密码等级)
Jan 05 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中global和$GLOBALS[]的分析之一
2012/02/02 PHP
php简单操作mysql数据库的类
2015/04/16 PHP
php两点地理坐标距离的计算方法
2018/12/29 PHP
Nginx+php配置文件及原理解析
2020/12/09 PHP
php中数组最简单的使用方法
2020/12/27 PHP
清空上传控件input file的值
2010/07/03 Javascript
javascript利用控件对windows的操作实现原理与应用
2012/12/23 Javascript
基于SVG的web页面图形绘制API介绍及编程演示
2013/06/28 Javascript
IE下使用jQuery重置iframe地址时内存泄露问题解决办法
2015/02/05 Javascript
jQuery移动页面开发中的触摸事件与虚拟鼠标事件简介
2015/12/03 Javascript
Nodejs中解决cluster模块的多进程如何共享数据问题
2016/11/10 NodeJs
bootstrap组件之按钮式下拉菜单小结
2017/01/19 Javascript
Angular实现响应式表单
2017/08/04 Javascript
vue2.0 资源文件assets和static的区别详解
2018/04/08 Javascript
vue-router history模式下的微信分享小结
2018/07/05 Javascript
使用Node搭建reactSSR服务端渲染架构
2018/08/30 Javascript
微信小程序常见页面跳转操作简单示例
2019/05/01 Javascript
ajax跨域访问遇到的问题及解决方案
2019/05/23 Javascript
使用localStorage替代cookie做本地存储
2019/09/25 Javascript
vue 导航内容设置选中状态样式的例子
2019/11/01 Javascript
[01:30]2016国际邀请赛中国区预选赛神秘商店火爆开启
2016/06/26 DOTA
PyQt5 QTable插入图片并动态更新的实例
2019/06/18 Python
Python获取统计自己的qq群成员信息的方法
2019/11/15 Python
Python基于模块Paramiko实现SSHv2协议
2020/04/28 Python
使用Python制作一盏 3D 花灯喜迎元宵佳节
2021/02/26 Python
利用CSS3的3D效果制作正方体
2020/03/10 HTML / CSS
Stylenanda中文站:韩国一线网络服装品牌
2016/12/22 全球购物
德国健康生活方式网上商店:Landkaufhaus Mayer
2019/03/12 全球购物
英国办公家具网站:Furniture At Work
2019/10/07 全球购物
好人好事演讲稿
2014/09/01 职场文书
2014年工程师工作总结
2014/11/25 职场文书
拔河比赛新闻稿
2015/07/17 职场文书
2019年预备党员的思想汇报:加深对党的认知
2019/09/25 职场文书
《雪域豹影》读后感:父爱的伟大
2019/12/23 职场文书
Mysql 性能监控及调优
2021/04/06 MySQL
GO语言字符串处理函数之处理Strings包
2022/04/14 Golang