Vue元件實現v-model的用法
阿新 • • 發佈:2019-01-19
簡單說明
當我們封裝一個元件,比如說MySelect
元件,我們希望他的用法是這樣的。
<my-select v-model="job">
<my-option value="dev">開發人員</my-option>
<my-option value="test">測試人員</my-option>
<my-option value="manager">管理人員</my-option>
</my-select>
這個用法很普遍,因為Vue本身對錶單元素的雙向繫結就是這麼使用的。但封裝這樣的元件我遇到最大的問題就是:無法對props中的value進行改變
所以我們需要先了解一下
v-model
的實現,下面就詳細說一下v-model的實現。
Vue對v-model的實現
如果我們不用v-model來實現雙向繫結,那麼我們需要這樣寫:
<template>
<input type="text" v-bind:value="name" @input="inputHandler"/>
<template>
<script>
export default {
data(){
return {
name: ''
}
},
methods: {
inputHandler(value){
if(value == null){
this.name = event.target.value;
}
else{
this.name = value;
}
}
}
}
</script>
- 我們通過vue的
v-bind
指令為input綁定了value,那麼在name值發生改變時,input的value也會發生改變。這樣就實現了資料驅動DOM
。(至於vue提供的bind是如何實現的,可以去了解一下Object.defineProperties
- 我們為input綁定了
input事件
,在事件處理函式中將event.target.value
賦值給name。這樣就實現了DOM驅動資料
的改變。
基於這兩個實現,就實現了DOM和資料的雙向繫結。很慶幸Vue對v-model的實現就是這樣的(跟官網的描述有些許不同,僅供參考)。可以看出,v-model實際上是通過:value
和@input
來實現的。並且inputHandler
中優先以傳入的引數value值給我們繫結的變數賦值,這一點很重要。這使得我們在元件中可以直接通過this.$emit('input', newValue)
來給外界的data屬性賦值。
綜上所述,我們簡單的對my-select元件進行封裝