此篇文章介绍的用法,vue的版本号>=3.4
作用
-
- 如果用在表单元素上,可实现输入框的内容与js中的变量进行双向绑定
-
- 如果用在组件上,可实现父值与本地变量之间的双向绑定
该篇文章介绍用在组件的v-model,即第二种
基本用法
使用defineModel()宏
在vite.config.ts中需新增如下配置:
export default defineConfig({
plugins: [
vue({
script: {
defineModel: true
}
})
]
})
<!-- Child.vue -->
<script setup>
// defineModel返回的值是Ref类型
const model = defineModel()
function update() {
model.value++
}
</script>
<template>
<button @click="update">changeModel</button>
<div>parent bound v-model is: {{ model }}</div>
</template>
<!-- Parent.vue -->
<Child v-model="count" />
当子组件的model的值发生改变时,父组件的count的值也一起改变
由于defineModel()返回的值是一个ref,所以我们能像修改其他ref一样,在本地修改ref的值,只不过这个ref的改变也会影响到父组件的值。
在子组件中也能使用v-model将defineModel()返回的ref绑定到一个原生input元素上
// Child.vue
<script setup>
const model = defineModel()
</script>
<template>
<input v-model="model" />
</template>
v-model 参数
// Parent.vue
<Child
v-model:title1="bookTitle1"
v-model:title2="bookTitle2"
/>
// Child.vue
<script setup>
const bookTitle1 = defineModel('title1')
const bookTitle2 = defineModel('title2')
</script>
<template>
<input type="text" v-model="bookTitle1">
<input type="text" v-model="bookTitle2">
</template>
defineModel参数
// 不带参数,默认props字段是modelValue
const title1 = defineModel()
// props的字段为modelValue,必传
const title2 = defineModel({
required: true
})
// v-model:title="xxx",props字段为title
const title3 = defineModel('title')
// v-model:title="xxx",props字段为title,必传
const title4 = defineModel('title', {
required: true
})
// 针对有自定义修饰符的情况,
const title5 = defineModel('title', {
// value为解包过的title5的值
get(value) {
},
set(value) {
}
})
v-model修饰符
v-model的内置修饰符:.trim .number .lazy,还可以自定义修饰符
// Parent.vue
<Child v-model:title.capitalize="bookTitle">
// Child.vue
<template>
<div>{{ title }}--{{ titleModifiers }}</div>
<input v-model="title" type="text">
</template>
<script setup>
const toUpperCase = str => str.charAt(0).toUpperCase() + str.slice(1)
const transformTitle = (str, capitalize) => capitalize ? toUpperCase(str) : str
// titleModifiers: { capitalize: true }
const [title, titleModifiers] = defineModel('title', {
get(value) {
console.log('title的值:', value)
return transformTitle(value, titleModifiers.capitalize)
},
set(value) {
return transformTitle(value, titleModifiers.capitalize)
}
})
</script>
自定义修饰符可以有多个,比如:
// Parent.vue
<Child v-model:title.capitalize.test="bookTitle">
// Child.vue
<script setup>
const [ title, titleModifier ] = defineModel('title')
// titleModifier为:{ capitalize: true, test: true }
</script>