前言
vue2.2+版本新增了一個功能,可以在自定義元件上使用v-model實現雙向繫結。在使用新功能之前,我們先來了解一下vue.js的v-model是如何實現雙向繫結的。從官方文件以及各種技術文章中,我們可以知道,v-model是v-bind以及v-on配合使用的語法糖,給一個詳細的例子:
<input v-model="value" />
<input v-bind:value="value" v-on:input="value= $event.target.value" />
複製程式碼
兩種方法的實現效果是一樣的,都是給<input>
標籤繫結一個值,並且在監聽到input事件時,把輸入的值替換繫結的值來實現雙向繫結。其中第一種是第二種方法的語法糖。
現在我們已經瞭解了v-model是什麼東東,那麼除了在表單控制元件上使用v-model外,能不能在自定義的元件上使用v-model,從而實現父子元件間的雙向繫結呢?
答案是可以的。 vue2.2+版本後,新增加了一個model選項,model選項允許自定義prop和event。官方原文是這樣的:允許一個自定義元件在使用 v-model 時定製 prop 和 event。預設情況下,一個元件上的 v-model 會把 value 用作 prop 且把 input 用作 event,但是一些輸入型別比如單選框和核取方塊按鈕可能想使用 value prop 來達到不同的目的。使用 model 選項可以迴避這些情況產生的衝突。
下面我們通過一個例項來講解怎麼使用:
我們首先編寫一個子元件,並用到model選項,核心程式碼如下:
<template>
<div class="radio">
<div class="radioGroup">
<div
class="radioItem"
v-for="item in options"
:key="item.value"
@click="clickRadio(item.value);"
>
<div
class="radioBox"
:class="{ checked: item.value === checked }"
></div>
<div class="name">{{ item.name }}</div>
</div>
</div>
</div>
</template>
<script>
export default {
name: "radio",
props: {
options: Array,
value: Number
},
computed: {
checked() {
return this.value;
}
},
model: {
prop: "value", //繫結的值,通過父元件傳遞
event: "update" //自定義時間名
},
methods: {
clickRadio(val) {
this.checked = val;
this.$emit("update", val); //子元件與父元件通訊,告知父元件更新繫結的值
}
},
watch: {
checked: function(newVal, oldVal) {
console.log("我是子元件,現在的值為:" + newVal);
alert("我是子元件,現在的值為:" + newVal);
}
}
};
</script>
複製程式碼
父元件部分:
<template>
<div id="app">
<div class="left">選中:{{checked}}</div>
<radio class="right" :options="options" v-model="checked"></radio>
</div>
</template>
<script>
import radio from './components/radio.vue'
export default {
name: 'App',
components: {
radio
},
data() {
return {
checked: 0,
options: [{
value: 0,
name: '選項1'
}, {
value: 1,
name: '選項2'
}]
}
}
}
</script>
複製程式碼