Vue3一个组件绑定多个 v-model,自定义 prop 和 event 名称
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)"
>
<input
type="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)"
>
<input
type="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
参数