之前学习vue2双向绑定的时候,为了加深理解,写了一篇文章 Vue 自定义组件实现v-model双向绑定,最近想着vue3也发布这么久了,就想着看看怎么在vue3中自定义组件怎么实现双向绑定。也想着最近每隔一周就写一篇关于vue3的文章,慢(懒)的话,就两周写一篇。
其实vue3的v-model跟vue2的使用区别不大,只是跟vue2的sync
修饰符进行了合并,所以在vue3中就移除了 sync
修饰符。下面我们看看怎么在composition api
中怎么写v-model
// 自定义一个TestModel组件
<template>
<div>
<input type="text" :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />
</div>
</template>
<script>
export default {
props: {
modelValue: {
type: String
}
}
}
</script>
然后在别的地方使用
// 引用TestModel组件
<template>
<h1>vue3中使用v-model {{msg}}</h1>
<testModel v-model="msg"></testModel>
<!-- 等同于下面语法 默认传入一个modelValue 然后子组件接收这个modelValue -->
<testModel :modelValue="msg" @update:modelValue="msg = $event"></testModel>
</template>
<script>
import { ref } from 'vue';
import testModel from './TestModel.vue';
export default {
components: {
testModel
},
setup(){
const msg = ref('')
return { msg }
},
}
</script>
当然我们可能不想叫modelValue
,也可以改成其他的名字,需要这样改写一下
// 父组件
<template>
<h1>vue3中使用v-model {{msg}}</h1>
<testModel v-model:msg="msg"></testModel>
</template>
子组件接收的props就要改成msg了
// 子组件
<template>
<div>
<input type="text" :value="msg" @input="$emit('update:msg', $event.target.value)" />
</div>
</template>
<script>
export default {
props: {
msg: {
type: String
}
}
}
</script>
双向绑定不一定必须是输入框组件,可以自定义各种各样的组件,比如通过click事件改变父组件的值
// 父组件
<template>
<div>{{count}}</div>
<testModel v-model:count="count"></testModel>
</template>
<script>
export default {
components: {
testModel
},
setup(){
const count = ref(0)
return { count }
}
}
</script>
// 子组件
<template>
<!-- 一定是+1 不是+=1 或者++ 否则vue会触发一个不让子组件直接改变props的警告 -->
<div @click="$emit('update:count', count + 1)">click me count + 1!</div>
</template>
<script>
export default {
props: {
count: {
type: Number
}
}
}
</script>