3.4 组件v-model
3.4.1 基本用法
v-model 可以在组件上使用以实现双向绑定。
vue
<!-- Child.vue -->
<script setup>
const model = defineModel()
function update() {
model.value++
}
</script>
<template>
<div>Parent bound v-model is: {{ model }}</div>
<button @click="update">Increment</button>
</template>
html
<!-- Parent.vue -->
<Child v-model="countModel" />
底层机制
3.4之前旧式处理方式
vue
<!-- Child.vue -->
<script setup>
const props = defineProps(['modelValue'])
const emit = defineEmits(['update:modelValue'])
</script>
<template>
<input
:value="props.modelValue"
@input="emit('update:modelValue', $event.target.value)"
/>
</template>
html
<!-- Parent.vue -->
<Child
:modelValue="foo"
@update:modelValue="$event => (foo = $event)"
/>
js
// 使 v-model 必填
const model = defineModel({ required: true })
// 提供一个默认值
const model = defineModel({ default: 0 })
3.4.2 v-model的参数
html
<MyComponent v-model:title="bookTitle" />
vue
<!-- MyComponent.vue -->
<script setup>
// const title = defineModel('title')
const title = defineModel('title', { required: true })
</script>
<template>
<input type="text" v-model="title" />
</template>
3.4.3 多个v-model绑定
html
<UserName
v-model:first-name="first"
v-model:last-name="last"
/>
vue
<script setup>
const firstName = defineModel('firstName')
const lastName = defineModel('lastName')
</script>
<template>
<input type="text" v-model="firstName" />
<input type="text" v-model="lastName" />
</template>
3.4.4 处理v-model修饰符
html
<MyComponent v-model.capitalize="myText" />
vue
<script setup>
const [model, modifiers] = defineModel({
set(value) {
if (modifiers.capitalize) {
return value.charAt(0).toUpperCase() + value.slice(1)
}
return value
}
})
</script>
<template>
<input type="text" v-model="model" />
</template>
带参数的 v-model 修饰符
html
<UserName
v-model:first-name.capitalize="first"
v-model:last-name.uppercase="last"
/>
vue
<script setup>
const [firstName, firstNameModifiers] = defineModel('firstName')
const [lastName, lastNameModifiers] = defineModel('lastName')
console.log(firstNameModifiers) // { capitalize: true }
console.log(lastNameModifiers) // { uppercase: true }
</script>