Vue v-model組件封裝(相似彈窗組件)

v-model

v-model是vue的一個語法糖,限制在input和textarea等這些表單元素中,官網所給的例子也是僅限於表單組件vue

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)"
    >
  `
})
複製代碼
<base-checkbox v-model="lovingVue"></base-checkbox>
複製代碼

如今咱們若是想把v-model用到除表單以外的自定義組件中,該怎麼使用呢,其實官網所給的例子也比較清晰了,只是若是死腦筋的話,那就限制住了,沒錯說的就是我-.-.bash

<!--封裝的類彈窗組件-->
<template>
    <div>
        <div v-show="value">這是v-model的彈窗組件</div>
    </div>
</template>
<script>
export default {
    props:{
        value:{
            type:Boolean,
            default:false
        }
    }
}
</script>
複製代碼
<!--父組件-->
<template>
    <div>
        <v-model v-model="value"></v-model>
        <button @click="value=true">點擊顯示</button>
        <button @click="value=false">點擊消失</button>
    </div>
</template>
<script>
import VModel from "./Vmodel"
export default {
    components:{VModel},
    data:function(){
        return {
            value:true
        }
    }
}
</script>
複製代碼

其實這樣父組件這邊已經能夠經過v-model對顯示和消失進行控制了,可是封裝組件的value這個屬性名是不能修改的,必須叫value,叫value1就不能夠了函數

props:{
        value1:{  //失效
            type:Boolean,
            default:false
        }
    }
複製代碼

緣由,看源碼ui

function transformModel (options, data: any) {
  const prop = (options.model && options.model.prop) || 'value' //子組件不存在options.model,默認給value
  const event = (options.model && options.model.event) || 'input'//event="input"
  ;(data.attrs || (data.attrs = {}))[prop] = data.model.value
  const on = data.on || (data.on = {})
  const existing = on[event]  //undefined
  const callback = data.model.callback  //f()
  if (isDef(existing)) {  //false
    if (
      Array.isArray(existing)
        ? existing.indexOf(callback) === -1
        : existing !== callback
    ) {
      on[event] = [callback].concat(existing)
    }
  } else {
    on[event] = callback  //把回調賦值給監聽的函數
  }
}
複製代碼

so,咱們就能夠加上model屬性,進行代碼修改this

<template>
    <div>
        <div v-show="value">這是v-model的彈窗組件</div>
        <div @click="cancelClick">組件內部調用</div>
    </div>
</template>
<script>
export default {
    props:{
        value:{
            type:Boolean,
            default:false
        }
    },
    model:{
        prop:"value",
        event:'change'
    },
    methods:{
        cancelClick:function(){
            //內部調用這個方法能夠進行控制
            this.$emit("change",false)
        }
    }
}
</script>
複製代碼

固然咱們也能夠經過model屬性,對value這個屬性名進行修改,也是實現一樣的效果spa

bool:{
        type:Boolean,
        default:false
    },
model:{
    prop:"bool",
    event:'change'
}
複製代碼

注意若是滅有加model屬性的話,對props的value屬性名修改的話,是沒效果的,默認的v-model的event默認修改的仍是valuecode

const prop = (options.model && options.model.prop) || 'value' //子組件不存在options.model,默認給value
  const event = (options.model && options.model.event) || 'input'//event="input"
複製代碼
相關文章
相關標籤/搜索