前言
v-model 可能大多数都是在表单输入里用,普通的表单传值和获取一般是这样:
<input :value="text" @input="event => text = event.target.value">
v-model帮我们简化了这些步骤:
<input v-model="text">
可以添加 .lazy, .number,.trim 对表单输入的内容做不同的操作。
然而随着项目里功能的构建,组件化是必不可少的一个操作,不仅能灵活业务模块,还能提高代码复用率,打造高内聚低耦合优质项目。
那么我们就来简单捋一捋组件之间的双向数据绑定。
用法
1. 选项式 api 使用
父组件
<SimpleDemo v-model="bar" />
子组件
<a-input type="text" :value="modelValue" @input="onSearchInput" />
props:{
modelValue:{
type:String
}
}
methods: {
onSearchInput(event: Event): void {
this.$emit("update:modelValue",event.target.value);
}
}
2. 使用 computed property 的功能来定义 getter 和 setter。
父组件
<SimpleDemo v-model="bar" />
子组件
<a-input type="text" class="demo-input" v-model:value="barValue" />
props:{
modelValue:{
type:String
}
}
computed:{
barValue: {
get(): string {
return this.modelValue;
},
set(v: string): void {
this.$emit("update:modelValue", v);
}
}
}
3. v-model 参数:默认情况下,组件上的 v-model 使用 modelValue 作为 prop 和 update:modelValue 作为事件。我们可以通过向 v-model 传递参数来修改这些名称:
选项式api:
父组件
<SimpleDemo v-model:foo="bar" />
子组件
<a-input type="text" class="demo-input" v-model:value="barValue" />
props:{
foo:{
type:String
}
}
computed:{
barValue: {
get(): string {
return this.foo;
},
set(v: string): void {
this.$emit("update:foo", v);
}
}
}
4. 在 选项式 setup时使用
父组件
<SimpleDemo v-model="bar" />
子组件
<a-input type="text" :value="modelValue" @input="onSearchInput" />
props:{
modelValue:{
type:String
}
}
setup(props, { emit }) {
const onSearchInput = (event: Event) => {
emit("update:modelValue", event.target.value);
};
return {
onSearchInput
};
}
5. 在组合式单文件组件时
父组件
<SimpleDemo v-model:visible="isVisible" />
子组件
<script lang="ts" setup>
const componentsProps = withDefaults(
defineProps<{
visible: boolean;
}>(),
{
visible: false
}
);
const componentEmits = defineEmits<{
(event: 'update:visible', visible: boolean): void
}>()
</script>
写在结尾
在vue3里还增加了能在单个组件实例上创建多个 v-model 双向绑定功能,其本质上来讲和单个v-model时没有太大区别,没增加一个双向绑定就多一个props。同样组件的 v-model 也支持自定义的修饰符,但不是介绍重点就不举例了,有兴趣的朋友可以自行了解一下。
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天,点击查看活动详情