vue+element 封装日期范围组件(双向绑定)

        像这样的日期组件,在后台管理项目中是比较多的,而且加了快捷选项,代码量较多,因此封装成组件。

        封装这一类型的组组件,主要是了解输入框双向绑定 v-model 的过程。

1、了解输入框双向绑定的过程:

官网:表单输入绑定 — Vue.js

  • 输入文本框:
  • 基础表单类型:
    • 不同的表单元素 v-model 在内部绑定的事件也不同:
      • text 和 textarea 元素使用 value property 和 input 事件;
      • checkbox 和 radio 使用 checked property 和 change 事件;
      • select 字段将 value 作为 prop 并将 change 作为事件。
  • 自定义组件的 v-model:
    • HTML 原生的输入元素类型并不总能满足需求。幸好,Vue 的组件系统允许你创建具有完全自定义行为且可复用的输入组件。这些输入组件甚至可以和 v-model 一起使用!具体使用方法如下
    •  要了解更多,请参阅组件指南中的自定义输入组件

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" class="dateRange-c"
                  type="daterange" unlink-panels format="yyyy-MM-dd" value-format="yyyy-MM-dd"
                  range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
                  :picker-options="pickerOptions" :align="align">
  </el-date-picker>
</template>

<script>
export default {
  name: "daterange",
  model:{
    prop: 'value',  
    event: 'change'    // 触发父组件中v-model绑定的属性发生改变的方法,名称自取
  },
  props:{
    //双向绑定的值 value: { type:[String,Array,Date], required: true, default: "" },
    value: { type:[String,Array,Date], required: true, default: "" },
    align: {type: String, default: "center"}
    
  },
  data(){
    return {
      // pickerOptions: {} //不需要快捷键
      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]);
          }
        }]
      }
    }
  },
  computed:{
    dataRange: {
      get(){
        if(this.val==null) this.val=""
        return this.value;
      },
      set(val){
        if(val==null) val=""
        this.$emit('change', val)
      }
    }
  },
  methods:{
    changeDaterange(val){
      // this.$emit("change", result);
    }
    //清空时值为null
  }
}
</script>

        注意:这里双向绑定时不要直接绑定到 props 传递的属性上,否则会报以下错误:

         大概意思是:避免直接改变属性,因为每当父组件重新渲染时,该值将被覆盖。相反,使用基于属性值的数据或计算属性。通过props传递给子组件的vModel,不能在子组件内部修改props中的vModel值。

3.2 父组件中使用

<date-range v-model="searchForm.operateTime"></date-range>

<script>
import dateRange from "@/components/selects/daterange.vue"
export default {
  components:{dateRange},
  data() {    
    return {
      //日期组件绑定的值,在父组件可以直接拿到进行使用
      searchForm: {
        operateTime: ""
      }
    }
  }
}
</script>

猜你喜欢

转载自blog.csdn.net/Start2019/article/details/126159962
今日推荐