前言
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>