Vue3一个组件绑定多个 v-model,自定义 prop 和 event 名称
Vue3
中v-mode
l默认使用modelValue
作为prop
,update:modelValue
作为事件,而Vue2
使用的是value
和input
。此外,Vue3允许通过参数的方式为组件添加多个v-model
绑定,例如v-model:title
和v-model:description
,每个都可以对应不同的prop
和事件。
例一
一个简单的双绑定
多个v-model
绑定,比如用户信息和权限设置。子组件接收两个v-model
,如userName
和isAdmin
,然后在子组件内部使用modelValue
和对应的update
事件。不过这里可能需要使用不同的参数,比如v-model:userName
和v-model:isAdmin
,然后子组件的props
应该是userName
和isAdmin
,事件则是update:userName
和update:isAdmin
。
基础用法 - 用户信息组件
ChildComponent.vue
<template><div><input :value="userName" @input="$emit('update:userName', $event.target.value)"><inputtype="checkbox":checked="isAdmin"@change="$emit('update:isAdmin', $event.target.checked)"></div>
</template><script setup>
defineProps(['userName', 'isAdmin']);
defineEmits(['update:userName', 'update:isAdmin']);
</script><!-- 父组件使用 -->
<!-- <UserForm v-model:user-name="userData.name" v-model:is-admin="userData.adminStatus"
/> -->
例二
一个自定义事件名称
例子可以涉及自定义prop
和事件名称,但根据Vue3
的文档,实际上通过v-model
的参数就可以直接指定prop
和事件,不需要额外配置。例如,v-model:title="pageTitle"
会自动使用title
作为prop
,update:title
作为事件
自定义参数 - 分页组件
Pagination.vue
<template><div><button @click="$emit('update:currentPage', currentPage - 1)">上一页</button><span>{{ currentPage }}/{{ totalPages }}</span><button @click="$emit('update:currentPage', currentPage + 1)">下一页</button></div>
</template><script setup>
defineProps(['currentPage', 'totalPages']);
defineEmits(['update:currentPage']);
</script><!-- 父组件使用 -->
<!-- <Pagination v-model:current-page="page" :total-pages="totalPages"
/> -->
注意:在
Vue3
中,每个v-model
绑定默认对应一个prop
和update
事件,因此自定义名称实际上是通过v-model
的参数来实现的。例如,v-model:userName
对应prop userName
和事件update:userName
。
例三
更复杂的对象传递,比如绑定整个对象,需要使用计算属性的getter
和setter
对象参数 - 颜色选择器
ColorPicker.vue
<template><input type="color" :value="color" @input="$emit('update:color', $event.target.value)"><inputtype="range":value="opacity"@input="$emit('update:opacity', $event.target.value)"min="0"max="1"step="0.1">
</template><script setup>
defineProps({color: String,opacity: Number
});
defineEmits(['update:color', 'update:opacity']);
</script><!-- 父组件使用 -->
<!-- <ColorPicker v-model:color="style.color" v-model:opacity="style.opacity"
/> -->
关键点总结:
- 使用
v-model:
参数名 语法实现多个绑定 - 子组件通过
defineProps
接收参数 - 通过
update:
参数名 事件触发更新 - 参数名会自动转换为
kebab-case
(如userName → user-name
) - 支持任意数量的
v-model
绑定 - 可以组合使用普通
props
和v-model
参数