可以在自定义组件上使用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>