Vue自定义组件如何实现v-model双向绑定
我们在使用Vue自定义组件的时候,通常是利用props和$emit来实现父子组件数据的传输,那么如何实现经典的v-model双向绑定呢。
v-model实际上是个语法糖,可以理解为<input v-bind:value=“value” v-on:input=“$emit(‘input’, $event.target.value)” /> ,我们需要使用这些特性去实现v-model,Vue2和Vue3实现略有不同。
Vue2实现
在Vue2中定义组件时,props为value的属性会默认接收v-model传过来的值,然后子组件向父组件传值时使用$emit(‘update’)回传。子组件编写因为根据规范子组件不能直接绑定props,所以定义了一个data.testValue,同时watch value实时更新testValue, testValue change也通过 this.$emit('update', event.target.value)
同步回传到父组件。
子组件代码:
<template> <input type="text" v-model="testValue" @change="testValueChange" /> </template> <script> export default { name: 'Child', props: { value: { type: String, default: '' } }, data() { return { testValue: '' } }, created() { this.testValue = this.value }, watch: { value() { this.testValue = this.value } }, methods: { testValueChange(event) { this.$emit('update', event.target.value) } }, } </script>
父组件代码
<template> <child v-mode="val" /> </template> <script> import Child from './Child.vue' export default { name: 'Parent', components: { Child } data() { return { val: '' } } } </script>
Vue3实现
Vue3实现方式略有不同,但原理是一致的,子组件props使用modelValue,回传父组件为emit(‘update:modelValue’)。
子组件代码:
<template> <input v-model="testValue" @change="testValueChange" /> </template> <script> import { ref, watch, onMounted } from 'vue' export default { name: 'Parent', props: { modelValue: { type: String, default: '' } }, setup(props, { emit }) { const testValue = ref('') onMounted(() => { testValue.value = props.modelValue }) watch( () => props.modelValue, (newVal) => { testValue.value = props.modelValue } ) testValueChange = (event) { emit('update:modelValue', event.target.value) } return { testValue, testValueChange } } } </script>
父组件代码:
<template> <child v-model="val" /> </template> <script> import { ref } from 'vue' import Child from 'Child.vue' export default { name: 'Parent', setup() { const val = ref('') return { val } } } </script>
近期评论