Vue3一个组件绑定多个 v-model,自定义 prop 和 event 名称
Vue3中v-model默认使用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参数