本文最后更新于 2023-03-14T00:05:02+08:00
v-model双向绑定
Vue 中使用 v-model 可以实现双向绑定
先看一个小栗子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| <template> <div id="app"> <p>{{ city }}</p> <input type="text" v-model="city" /> </div> </template> <script> export default { name: "App", data() { return { city: '北京' } }, }; </script>
|
city 的值通过 v-model 绑定到 input 上,因此它会根据 input 输入框的值进行动态变化。根据官方文档的解释,v-model 其实是一个语法糖,它会自动的在元素或者组件上面解析为 :value = " "
和 @input = " "
。所以我们可以将上述代码进行拆解:
1 2 3 4 5 6
| <template> <div id="app"> <p>{{ city }}</p> <input type="text" :value="city" @input="city = $event.target.value" /> </div> </template>
|
自定义组件v-model双向绑定
不使用 v-model,我们也可以得到相同的效果。上述代码中,当在 input 输入框输入内容时,会自动的触发 input 事件,更新绑定的 city 值为当前 input 框输入的值。所以,了解这些后,我们是否可以在自己写的组件上面实现 v-model 的效果呢?
官方文档:自定义组件的 v-model。这里我们将官网的栗子改造一下拿过来:
父组件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div id="app"> <p>{{ name }}</p> <!--自定义组件上使用 v-model,name 的值会传入到子组件 model-prop-text 中--> <CustomVModel v-model="name" /> </div> </template> <script> import CustomVModel from './components/CustomVModel' export default { name: "App", components: { CustomVModel }, data() { return { name: '张三' } }, }; </script>
|
子组件 CustomVModel.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <template> <input type="text" :value="text" @input="$emit('change', $event.target.value)" /> </template> <script> export default { model: { prop: 'text', // 可任意定义的变量,用来接收父组件 v-model 中传递过来的值 event: 'change' }, props: { text: String, // 对自己定义的变量的类型和默认值进行声明,必须和自己定义的变量名相同 default() { return '' } } } </script>
|
根据官方文档给出的说法:父组件中的 name 的值将会传入子组件中名为 text(该名称可自己定义:默认为value) 的 prop 中,同时子组件的 input 如果触发 @input 事件并附带一个新的值的时候,父组件中 name 的值也会被重新更新。当然,我们还是需要在子组件的 props 选项里声明 text 这个 prop。