vue 自定義封裝組件 使用 model 選項


自定義組件的 v-model

一個組件上的 v-model 默認會利用名為 value 的 prop 和名為 input 的事件,但是像單選框、復選框等類型的輸入控件可能會將 value 特性用於不同的目的model 選項可以用來避免這樣的沖突:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

現在在這個組件上使用 v-model 的時候:

<base-checkbox v-model="lovingVue"></base-checkbox>

這里的 lovingVue 的值將會傳入這個名為 checked 的 prop。同時當 <base-checkbox> 觸發一個 change 事件並附帶一個新的值的時候,這個 lovingVue 的屬性將會被更新。

注意你仍然需要在組件的 props 選項里聲明 checked 這個 prop。

 

原來的沒有封裝的代碼:

  <FormItem label="適用胸型" prop="chestShape">
        <Select multiple v-model="chestShape" @on-change="changeChestShape">
          <Option
            v-for="(item,index) in chestShapeReqList"
            :value="item.dictValue"
            :key="index"
          >{{ item.dictLabel }}</Option>
        </Select>
      </FormItem>

      <FormItem label="有無鋼圈" prop="hasSteel">
        <Select multiple v-model="hasSteel" @on-change="changeHasSteel">
          <Option
            v-for="(item,index) in hasSteelReqList"
            :value="item.dictValue"
            :key="index"
          >{{ item.dictLabel }}</Option>
        </Select>
      </FormItem>

      <FormItem label="功能" prop="hasFunction">
        <Select multiple v-model="hasFunction" @on-change="changwHasFunction">
          <Option
            v-for="(item,index) in hasFunctionReqList"
            :value="item.dictValue"
            :key="index"
          >{{ item.dictLabel }}</Option>
        </Select>
      </FormItem>

      <FormItem label="壓力" prop="pressure">
        <Select multiple v-model="pressure" @on-change="changePressure">
          <Option
            v-for="(item,index) in pressureReqList"
            :value="item.dictValue"
            :key="index"
          >{{ item.dictLabel }}</Option>
        </Select>
      </FormItem>

      <FormItem label="組合形式" prop="makeupType">
        <Select multiple v-model="makeupType" @on-change="changeMakeupType">
          <Option
            v-for="(item,index) in makeupTypeReqList"
            :value="item.dictValue"
            :key="index"
          >{{ item.dictLabel }}</Option>
        </Select>
      </FormItem>

這段代碼里面的相識度很高  我們可以封裝起來

 

子組件 :

新建文件  select/seclect.vue

 

<template>
      <FormItem :label="label" :prop="prop">
        <Select :multiple="multiple"   v-if="listData.length>0"    :value="modelValue" @change="updateVal($event.target.value)" >
          <Option
            v-for="(item,index) in listData"
            :value="item.dictValue"
            :key="index"
          >{{ item.dictLabel }}</Option>
        </Select>
      </FormItem>
</template>
<script>
export default {
  name: 'com-select',
  props: {
    listData: {
      type: Array,
      default: () => []
    },
    label:String,
    multiple:Boolean,
    prop:String,
    modelValue:Array,
  },
   model: {
    prop: 'modelValue',
    event: 'selectData'
  },
  data () {
    return {
       
    }
  },
  computed: {
   
  },
  methods: {
        updateVal(val){
            this.$emit('selectData',val)
        }

  }
}
</script>

從官網上看到,v-model在內部為不同的輸入元素使用不同的屬性並拋出不同的事件:

text和textarea元素使用value屬性和input事件

checkbox和radio使用checked屬性和change事件

select使用value和change事件

 

因為自定的組件並沒有默認的value和input事件,在使用時,我們需要按照上面那樣顯式的去聲明定義這些東西。這時,需要model選項,在定義組件的時候,指定prop的值和監聽的事件。

 

 model: {
    prop: 'modelValue',
    event: 'selectData'
  },

model 選項中的prop   對應 =》   :value="modelValue"  的名字

model 選項中的   event   對應的是    this.$emit('selectData',val)  的  事件名字   this.$emit('selectData',val)

props  里面 的是    通過props傳遞,實現父組件值綁定到子組件的屬性值
 
 

 

父組件:

 

引入子組件

import SelectCom from '../../components/Select/Select'

 

使用組件

  components: {
       SelectCom 
  },
  <SelectCom  label="基礎風格"  :listData="productStyleList"  v-model="sty"   prop="style"   :multiple="multiple"    @selectData="styl(e)" />  
productStyleList  是傳遞進去的數組   
v-model="sty"  雙向綁定的值

@selectData="styl(e)"  : 觸發的事件

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM