像这样的日期组件,在后台管理项目中是比较多的,而且加了快捷选项,代码量较多,因此封装成组件。
封装这一类型的组组件,主要是了解输入框双向绑定 v-model 的过程。
1、了解输入框双向绑定的过程:
官网:表单输入绑定 — Vue.js
- 输入文本框:
- 输入框的双向绑定 v-model,实际上是一个语法糖,等价于:
-
value="uname"
@input="uname=$event.target.value"
-
- 示例:Vue组件封装 ——input 输入框组件_黑猫了个怪怪的博客-CSDN博客_vue输入框
- 输入框的双向绑定 v-model,实际上是一个语法糖,等价于:
- 基础表单类型:
- 不同的表单元素 v-model 在内部绑定的事件也不同:
- text 和 textarea 元素使用
value
property 和input
事件; - checkbox 和 radio 使用
checked
property 和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
- text 和 textarea 元素使用
- 不同的表单元素 v-model 在内部绑定的事件也不同:
- 自定义组件的 v-model:
- HTML 原生的输入元素类型并不总能满足需求。幸好,Vue 的组件系统允许你创建具有完全自定义行为且可复用的输入组件。这些输入组件甚至可以和
v-model
一起使用!具体使用方法如下: -
要了解更多,请参阅组件指南中的自定义输入组件。
- HTML 原生的输入元素类型并不总能满足需求。幸好,Vue 的组件系统允许你创建具有完全自定义行为且可复用的输入组件。这些输入组件甚至可以和
2、代码
官网——props验证:Prop — Vue.js
了解以上 v-model 绑定的原理以及 props验证关系 之后,封装这个组件就简单多了。根据 ELement 文档 可以知道,这个组件双向绑定配合的事件是 change,接下来就开始编写代码,父子组件通讯的字段按照自己的需求通过 props 来绑定即可。
2.1 子组件
在 components 文件夹下新建一个文件用来写子组件,我这里的路径是:@/components/selects/daterange.vue,复制以下代码:
<template><el-date-picker v-model="dataRange" @change="changeDaterange"type="daterange" unlink-panels format="yyyy-MM-dd"range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" value-format="yyyy-MM-dd":picker-options="pickerOptions" :align="align"></el-date-picker>
</template><script>
export default {name: "daterange",model:{prop: 'value', event: 'change' // 触发父组件中v-model绑定的属性发生改变的方法,名称自取},props:{//双向绑定的值 valuevalue: { type:[String,Array,Date], required: true, default: "" },align: {type: String, default: "center"}},data(){return {pickerOptions: {shortcuts: [{text: '最近一周',onClick(picker) {const end = new Date();const start = new Date();start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);picker.$emit('pick', [start, end]);}}, {text: '最近一个月',onClick(picker) {const end = new Date();const start = new Date();start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);picker.$emit('pick', [start, end]);}}, {text: '最近三个月',onClick(picker) {const end = new Date();const start = new Date();start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);picker.$emit('pick', [start, end]);}}]},dataRange: this.value}},methods:{changeDaterange(val){let result = val?val: ""; //清空时值为null,在这里判断一下,否则会报错this.$emit("change", result); }}
}
</script>
注意:这里双向绑定时不要直接绑定到 props 传递的属性上,否则会报以下错误:
大概意思是:避免直接改变属性,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于属性值的数据或计算属性。通过props传递给子组件的vModel,不能在子组件内部修改props中的vModel值。
3.2 父组件中使用
<my-daterange :vModel="dateRange"></my-daterange><script>
import myDaterange from "@/components/selects/daterange.vue"
export default {components:{myDaterange},data() { return {dateRange: "" //日期组件绑定的值,在父组件可以直接拿到进行使用}}
}
</script>