vue 组件上使用v-model以实现双向绑定
v-model 实际上就是 $emit('input') 以及 props:value 的组合语法糖,只要组件中满足这两个条件,就可以在组件中使用 v-model。,子组件中触发更新需要通过emit 触发update:modelValue自定义事件。父组件调用子组件,通过v-model绑定属性值,在子组件中默认接收props为。在下面的组件中,我们声明了。这个 prop,它的默认值是一个空对象。绑
·
默认情况
v-model 实际上就是 $emit('input') 以及 props:value 的组合语法糖,只要组件中满足这两个条件,就可以在组件中使用 v-model
父组件调用子组件,通过v-model绑定属性值,在子组件中默认接收props为modelValue
,子组件中触发更新需要通过emit 触发update:modelValue自定义事件。
// 父组件调用子组件
<SubInput
v-model="formState.title0"
/>
// 子组件
<input :value="modelValue" @input="($event: any) => $emit('update:modelValue', $event.target.value)" />
props: {
modelValue: { type: String, require: true }
},
emit: ['update:modelValue'],
传参
默认情况下,v-model
在组件上都是使用 modelValue
作为 prop,并以 update:modelValue
作为对应的事件。我们可以通过给 v-model
指定一个参数来更改这些名字:
在这个例子中,子组件应声明一个 title
prop,并通过触发 update:title
事件更新父组件值:
// 父组件调用子组件
<SubInput v-model:title1="formState.title1" />
// 子组件
<input :value="title1" @input="($event: any) => $emit('update:title1', $event.target.value)" />
props: {
title1: { type: String, require: true },
},
emit: [ 'update:title1'],
v-model
修饰符
组件的 v-model
上所添加的修饰符,可以通过 modelModifiers
prop 在组件内访问到。在下面的组件中,我们声明了 modelModifiers
这个 prop,它的默认值是一个空对象。
对于又有参数又有修饰符的 v-model
绑定,生成的 prop 名将是 arg + "Modifiers"
// 父组件调用子组件
<SubInput
v-model.capitalize="formState.title0"
v-model:title2.capitalize="formState.title2"
/>
// 子组件
<input :value="title2" @input="handleTitle2" />
props: {
modelModifiers: { default: () => ({}) },
title2Modifiers: { default: () => ({capitalize: false}) },
},
// 对于传递了capitalize修饰符的输入进行自动转换首字母大写的处理
const handleTitle2 = (e: any) => {
let value = e.target.value;
if (props.title2Modifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
emit('update:title2', value)
}
onMounted(() => {
// 无参数有修饰符生成的prop名:modelModifiers
console.log('modelModifiers: ' , props.modelModifiers)
// 有参数且有修饰符生成的 prop名:arg + "Modifiers"
console.log('title2Modifiers: ', props.title2Modifiers)
})
使用一个可写的,同时具有 getter 和 setter 的 computed 属性
// 父组件
<SubSelect v-model="formState.province" />
// 子组件
<template>
<a-divider orientation="right">使用一个可写的,同时具有 getter 和 setter 的 computed 属性</a-divider>
<div>省份:</div>
<a-select
v-model:value="value"
show-search
allowClear
placeholder="input"
:style="{ width: '200px' }"
:options="provinces"
:filter-option="filterOption"
></a-select>
</template>
<script lang="ts">
import { defineComponent, computed } from 'vue';
import { provinces } from '@/utils/consts';
export default defineComponent({
props: {
modelValue: { type: String, require: true },
},
emit: ['update:modelValue'],
setup(props, { emit }) {
const value = computed({
get() {
return props.modelValue;
},
set(value) {
emit('update:modelValue', value);
},
});
const filterOption = (input: string, option: any) => {
return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0;
};
return {
filterOption,
value,
provinces
};
},
});
</script>
更多推荐
已为社区贡献2条内容
所有评论(0)