当前位置:
首页 > temp > JavaScript教程 >
-
封装一个日期组件,提交数据为字符串——dateStingPicker
dateStingPicker组件封装
需求:
- 页面中使用日期选择框,输入框中回显日期格式“XXXX年XX月XX日”
- 提交数据时将日期格式转换为字符串,如:“20210314”
- 查看时,回显数据日期格式同样为“XXXX年XX月XX日”
演示实例
序——使用软件及框架版本
- vue 2.6.11
- ant-design-vue 1.7.1
- moment.js(日期转换依赖)
设计思路
-
根据需求,可以知道需要回显格式需要为“XXXX年XX月XX日”,查看组件库
a-date-picker
,了解到format
属性可以将在输入框中数据转换为特定格式。 -
在提交数据时,由于我们是封装组件,给其他页面中使用,所以需要将需要提交的值由子组件置到父组件上,所以在日期组件中选中日期出发的事件
change
/input
,在选中日期的时候需要使用到$emit
,将值置到上层副组件。 - 在回显数据时,查看页面数据的时候,表单上显示数据,此时从后台数据中拿到的是字符串“20210314”,同时需要将数据格式化为“XXXX年XX月XX日”,显示在输入框中。
具体代码过程
1. template模板区域
<template>
<div>
<!-- 这里momVal是momentValue的缩写,因为value的真实值是moment对象 -->
<a-date-picker
:value="momVal"
:allowClear="allowClear"
:disabled="disabled"
:format="dateFormat"
:mode="mode"
:placeholder="placeholder"
@change="dateChanged"
>
</a-date-picker>
</div>
</template>
在这里用到几个属性,
-
由于是封装组件,所以使用
value
实现数据的双向绑定,在表单中使用allClear
的时候在点击清除按钮时也可以清除表单显示和底层数据。 - mode是输入框显示模式,date、month、year可选,但是year模式时不太好用,具体可以参考下一篇,year年份组件封装。
-
当然组件上不止有
@change
事件,@blur
,@select
都是可以使用的,可以根据项目需求来具体使用,不过在父组件上使用事件时,需要在子组件props
中声明,并在模板部分使用双向绑定:select="select"
。
2. js区域
<script>
import moment from 'moment'
export default {
name: 'dateStringPicker',
props: {
value: {
type: [String, Number],
default: ''
},
// 返回的日期格式
dateFormat: {
type: String,
default: 'YYYY年MM月DD日'
},
// 类型,选择年份请传入"year",选择年月请传入"month"
mode: {
type: String,
default: 'date'
},
placeholder: {
type: String,
default: '请选择日期'
},
disabled: {
type: Boolean,
default: false
},
allowClear: {
type: Boolean,
default: true
},
// 判断输入的两种状态input/change
triggerChange: {
type: Boolean,
default: true
}
},
data () {
const dateStr = this.value
return {
// 由于vue是数据驱动页面加载的,所以在data中需要给value一个初始值
momVal: !dateStr ? null : moment(dateStr, this.dateFormat),
lastValue: ''
}
},
watch: {
// 此处的监听,用来实现设计思路3
value (val) {
if (!val) {
this.momVal = null
} else {
this.momVal = moment(val, 'YYYYMMDD')
}
}
},
methods: {
moment,
// 此处change事件,用来实现设计思路2,此处有注意事项,当时写的时候还是遇到一些问题的
dateChanged (mom) {
// 参考注意事项3
if (!mom) {
if (this.triggerChange) {
this.$emit('change', null)
} else {
this.$emit('input', null)
}
} else {
// 参考注意事项1
this.lastValue = moment(mom).format('YYYYMMDD')
// 参考注意事项2
if (this.triggerChange) {
this.$emit('change', this.lastValue
} else {
this.$emit('input', this.lastValue)
}
}
}
}
}
</script>
注意事项:
-
在提交数据的时候需要提交给表单的数据我们通过
lastValue
传递;如果不需要格式转换可以直接使用this.momVal = value
这样传递的数据类型还是moment对象。 -
生造一个
triggerChange
属性的原因是,在ant-design-vue组件中,使用a-form表单组件的时候,分了两种情况-
提交数据时不需要校验规则,使用
v-model
绑定数据 -
提交数据时需要校验规则,使用
v-decorator
在使用
v-model
时,点击日期触发的事件时input
,而在使用v-decorator
时,点击日期触发的事件时change
-
提交数据时不需要校验规则,使用
-
为什么要在提交数据的
change
事件中,添加一个!mom
的条件判断,原因是:在表单上添加allClear
属性之后,表单中会出现可以清除当前输入框数据的符号“❌”,在清除表单数据的时候,表单上回显示no valid
或者NaN
,原因可能是清除之后表单的初始值数据类型不对,这点我也不是太清楚。总之,解决方法就是添加一个!mom
的条件判断,在清除表单数据的时候重新给表单value赋一个空值null
,因为value的类型是对象,所以不能是""
。
测试demo实例
<template>
<div>
<div class="box">
<h1>this is dateStringPiker</h1>
<div class="btn">
<a-button type="primary" @click="click"> 提交数据</a-button>
</div>
<a-form :form="editForm" layout="inline">
<!-- 使用v-model时,是以input事件从子组件抛出value值 -->
<a-form-item label="v-model形式的绑定的 日期">
<date-string-picker
v-model="editForm.date"
:trigger-change="false">
</date-string-picker>
</a-form-item>
<!-- 在需要校验的情况下,在表单中使用v-decorator的形式绑定,
同时自组件要以change的形式将value抛出到上层副组件 -->
<!-- <a-form-item label="v-decorator形式绑定的 日期">-->
<!-- <date-string-picker-->
<!-- v-decorator="['date',{initialValue:''}]"-->
<!-- :trigger-change="true">-->
<!-- </date-string-picker>-->
<!-- </a-form-item>-->
</a-form>
</div>
</div>
</template>
<script>
import dateStringPicker from '@/component/dateStringPicker'
export default {
name: 'demo',
components: {
dateStringPicker
},
data() {
return {
// 使用v-decorator要使用下面方法注册form表单
// editForm: this.$form.createForm(this)
// v-model的形式,form表单注册则比较简单
editForm: {
date: ''
}
}
},
methods: {
click() {
console.log('点击按钮')
// v-model绑定测试提交
// console.log(this.editForm)
// v-decorator绑定,测试数据提交
this.editForm.validateFields((err, value) => {
console.log(err)
console.log(value)
})
}
}
}
</script>
<style scoped lang="less">
.box {
margin: 30px 30px;
}
.btn {
margin: 30px 30px;
}
</style>
Find me
Gitee:https://gitee.com/heyhaiyon/ant-vue-admin.git
出处:https://www.cnblogs.com/heyhaiyang/p/14533013.html
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数