在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 操作DOM案例代码分享
Apr 05 Javascript
jQuery.extend 函数的详细用法
Jun 27 Javascript
jQuery旋转插件—rotate支持(ie/Firefox/SafariOpera/Chrome)
Jan 16 Javascript
jQuery代码实现对话框右上角菜单带关闭×
May 03 Javascript
Three.js快速入门教程
Sep 09 Javascript
js仿小米官网图片轮播特效
Sep 29 Javascript
vue.js学习笔记之绑定style样式和class列表
Oct 31 Javascript
微信小程序开发之数据存储 参数传递 数据缓存
Apr 13 Javascript
vue按需加载组件webpack require.ensure的方法
Dec 13 Javascript
如何使用vuex实现兄弟组件通信
Nov 02 Javascript
简单了解JavaScript异步
May 23 Javascript
vue的注意规范之v-if 与 v-for 一起使用教程
Aug 04 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使用pear自带的mail类库发邮件的方法
2015/07/08 PHP
PHP MVC框架skymvc支持多文件上传
2016/05/26 PHP
PHP中函数gzuncompress无法使用的解决方法
2017/03/02 PHP
PHP开发之用微信远程遥控服务器
2018/01/25 PHP
laravel 错误处理,接口错误返回json代码
2019/10/25 PHP
显示、隐藏密码
2006/07/01 Javascript
jQuery 中关于CSS操作部分使用说明
2007/06/10 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
JavaScript中的运算符种类及其规则介绍
2013/09/26 Javascript
jQuery判断checkbox是否选中的3种方法
2014/08/12 Javascript
jquery动态改变div宽度和高度
2015/02/09 Javascript
jquery通过closest选择器修改上级元素的方法
2015/03/17 Javascript
相册展示PhotoSwipe.js插件实现
2016/08/25 Javascript
JS+HTML5实现的前端购物车功能插件实例【附demo源码下载】
2016/10/17 Javascript
JS中IP地址与整数相互转换的实现代码
2017/04/10 Javascript
详解webpack 多页面/入口支持&amp;公共组件单独打包
2017/06/29 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
NodeJS实现视频转码的示例代码
2017/11/18 NodeJs
浅谈vue的几种绑定变量的值 防止其改变的方法
2018/03/01 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
2019/02/28 Javascript
[47:43]Alliance vs KG 2019国际邀请赛小组赛 BO2 第一场 8.16
2019/08/18 DOTA
Python队列的定义与使用方法示例
2017/06/24 Python
Python 多进程并发操作中进程池Pool的实例
2017/11/01 Python
python实现发送form-data数据的方法详解
2019/09/27 Python
澳大利高级泳装品牌:Bondi Born
2018/05/23 全球购物
为您的家、后院、车库等在线购物:Spreetail
2019/06/17 全球购物
英国排名第一的宠物店:PetPlanet
2020/02/02 全球购物
会计职业生涯规划书
2014/01/13 职场文书
幼儿园父亲节活动方案
2014/03/11 职场文书
乡党政领导班子群众路线教育实践活动个人对照检查材料
2014/09/20 职场文书
房地产销售经理岗位职责
2015/02/02 职场文书
元旦主持词开场白
2015/05/29 职场文书
如何才能写好调研报告?
2019/07/03 职场文书
python基础入门之普通操作与函数(三)
2021/06/13 Python
Vue的过滤器你真了解吗
2022/02/24 Vue.js
PYTHON使用Matplotlib去实现各种条形图的绘制
2022/03/22 Python