前言
本文主要描述Vue3.4新API defineModel
,它在实际开发中使用场景非常广泛。主要替代了传统的prop + emit的方式,用更简短的代码来处理父子组件中的数据双向绑定。
写法对比
.sync修饰符
html
/* 父组件 */
<template>
<div>
<Child-component :count.sync="count" />
</div>
</template>
<script>
export default {
components: {
'ChildComponent': () => import('@/components/ChildComponent.vue')
},
data() {
return {
count: 0
}
}
}
</script>
html
/* 子组件 */
<script>
export default {
props: {
count: {
type: Number,
default: 0
}
},
methods: {
handleCountChange() {
this.count = 1
}
}
}
</script>
emit()
html
/* 父组件 */
<template>
<div>
<Child-component :count="count" />
</div>
</template>
<script>
export default {
components: {
'ChildComponent': () => import('@/components/ChildComponent.vue')
},
data() {
return {
count: 0
}
}
}
</script>
html
/* 子组件 */
<script>
export default {
props: {
count: {
type: Number,
default: 0
}
},
methods: {
handleCountChange() {
this.$emit('update:count',1)
}
}
}
</script>
defineModel()
html
/* 父组件 */
<template>
<div>
<Child-component v-model="count" />
</div>
</template>
<script setup>
const count = ref(0)
</script>
html
/* 子组件 */
<script setup>
const count = defineModel()
const handleCountChange = () => {
count.value ++
}
</script>
修饰符
当遇到需要使用修饰符时,需要解构defineModel()
的返回值,这里官方文档提供了示例
html
/* 父组件 */
<script setup>
const [modelValue, modelModifiers] = defineModel()
// 为 true 时说明父组件使用了这个修饰符
if(modelModifiers.trim) {
// 需要手写处理trim
}
</script>
html
/* 子组件 */
<script setup>
const [modelValue, modelModifiers] = defineModel({
// get() 省略了,因为这里不需要它
set(value) {
// 如果使用了 .trim 修饰符,则返回裁剪过后的值
if (modelModifiers.trim) {
return value.trim()
}
// 否则,原样返回
return value
}
})
</script>
绑定多个数据
html
/* 父组件 */
<template>
<Child-component
v-model="count"
v-model:visible="visible"
v-model:arr="arr"
/>
</template>
<script setup>
const count = ref(0)
const visible = ref(false)
const arr = ref([])
</script>
html
/* 子组件 */
<script setup>
const count = defineModel()
const visible = defineModel("visible", { default: false })
const arr= defineModel("arr", { default:() => [] })
</script>
typescript写法
html
<script setup lang="ts">
const count = defineModel<number>()
const visible = defineModel<boolean>("visible", { default: false })
const arr= defineModel<[]>("arr", { default:() => [] })
</script>