First, we need to use two advanced application properties in the Vue API

  • vm.$attrs
  • vm.$listeners
  • Use v-Models on components

Custom events can also be used to create custom input components that support V-Models. Remember:

<input v-model="searchText">
Copy the code

Is equivalent to:

<input
  v-bind:value="searchText"
  v-on:input="searchText = $event.target.value"
>
Copy the code

When used with components, the V-Model looks like this:

<custom-input
  v-bind:value="searchText"
  v-on:input="searchText = $event"
></custom-input>
Copy the code

In order for it to work, the inside the component must: bind its value attribute to a prop named Value. When its input event is raised, the new value is thrown by a custom input event in code that looks like this:

Vue.component('custom-input', {
  props: ['value'],
  template: `
    <input
      v-bind:value="value"
      v-on:input="$emit('input', $event.target.value)"
    >`})Copy the code

The V-Model should now work perfectly on this component:

<custom-input v-model="searchText"></custom-input>
Copy the code

That’s about all you need to know about component custom events so far, and if you’ve read this page and got a handle on it, we recommend you come back and finish reading custom events.

Secondary encapsulation of button components

<template>
  <div>
    <el-button v-bind="$attrs" v-on="$listeners" icon="el-icon-search" type="primary">{{btnName}}</el-button>
  </div>
</template>

<script>
export default {
  name: 'd2Button'.props: {
    btnName: {
      type: String.default: 'search'}}}</script>
Copy the code

How to use a button with a secondary wrapper

/ / Vue.com registered components ponent (d2 - button, () = > import ('/d2 - button '))<d2-button/>
Copy the code

Secondary encapsulation of the date selection component

<template>
  <div class="el-input-group">
    <div class="el-input-group__prepend" v-if="pickerName">{{pickerName}}</div>
    <el-date-picker v-bind="$attrs" value-format="timestamp" v-on="$listeners" :value="value" @change="change($event)" :type="type" :picker-options="pickerOptions" range-separator="To" start-placeholder="Start Date" end-placeholder="End Date" align="right"/>
  </div>
</template>

<script>
export default {
  name: 'd2DateTimePicker'.props: {
    type: {
      type: String.default: 'datetimerange'
    },
    value: {
      type: Array.default: () = >[]},pickerName: {
      type: String.default: ' '
    }
  },
  data () {
    return {
      pickerOptions: {
        shortcuts: [{
          text: 'Last Week',
          onClick (picker) {
            const end = new Date(a)const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: 'Last Month',
          onClick (picker) {
            const end = new Date(a)const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
            picker.$emit('pick', [start, end])
          }
        }, {
          text: 'Last 3 months',
          onClick (picker) {
            const end = new Date(a)const start = new Date()
            start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
            picker.$emit('pick', [start, end])
          }
        }]
      }
    }
  },
  watch: {
    value (newVal) {
      this.$emit('input', newVal)
      this.$emit('change', newVal)
    }
  },
  methods: {
    change ($event) {
      this.$emit('input', $event.target.value)
      this.$emit('change', $event.target.value)
    }
  }
}
</script>

<style lang="scss" scoped>
.el-input-group {
  line-height: normal;
  display: inline-table;
  width: auto;
  border-collapse: separate;
  border-spacing: 0;
}
</style>
Copy the code

use

<d2-date-time-picker pickerName="Time frame" v-model="searchParams.orderTimer"/>Secondary encapsulation input<template>
  <el-input v-bind="$attrs" v-on="$listeners" class="mw300 d2-mr" :value="value" @input="input" :placeholder="placeholder">
    <template slot="prepend" v-if="inputName">{{inputName}}</template>
  </el-input>
</template>

<script>
export default {
  name: 'd2Input'.props: {
    value: {
      type: [Number.String.Array]},inputName: {
      type: String.default: ' '
    },
    placeholder: {
      type: String.default: ' '}},methods: {
    input ($event) {
      this.$emit('input', $event.target.value)
    }
  }
}
</script>
Copy the code

use

<d2-input inputName="Order Number" v-model="searchParams.orderNum" :clearable="true" placeholder="Please enter the order number"/>
Copy the code

Secondary encapsulation SELECT

<template>
  <div class="el-input-group el-input-group--prepend mw300 d2-mr">
    <div class="el-input-group__prepend" v-if="selectName">{{selectName}}</div>
    <el-select v-bind="$attrs" :value="selectData" @input="change($event)" :placeholder="placeholder">
      <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"/>
    </el-select>
  </div>
</template>

<script>
export default {
  name: 'd2Select'.props: {
    value: [Number.String.Array].selectName: {
      type: String.default: ' '
    },
    options: {
      type: Array.default: () = >[]},placeholder: {
      type: String.default: ' '
    }
  },
  data () {
    return {
      selectData: this.value
    }
  },
  watch: {
    'value' (newValue) {
      this.selectData = newValue
      this.$emit('input', newValue)
    }
  },
  created () {
    this.selectData = this.value
  },
  methods: {
    change (val) {
      this.$emit('input', val)
    }
  }
}
</script>
Copy the code

use

<d2-select selectName="Order Status" :options="orderStatus" v-model="searchParams.orderStatus" :clearable="true" placeholder="Please select order status"/>
Copy the code

The specific effects are as follows: