组件
v-model: 组件 v-model
defineModel宏: definemodel
vue中提供的 v-model 可以在表单标签(<input>等 )上使用以实现双向绑定
同样的, 在自定义组件中也可使用 v-model实现双向绑定, 但子组件需要做对应的处理才可以
随着vue3.4的发布, 现在可以使用defineModel简化双向绑定的写法
v-module语法糖
我们知道VUE是单向数据流, v-model指令的双向绑定实际是一个语法糖
<input v-model="text" />
<!-- 等价于 -->
<input :value="text" @input="event => text = event.target.value" />
另外,v-model 还可以用于各种不同类型的输入,、 元素。它会根据所使用的元素自动使用对应的 DOM 属性和事件组合
组件的v-module
在VUE3.4 之前, 为了实现组件的v-module需要在子组件自己处理prop和事件, 有时候为了在子组件更方便的使用父组件双向绑定的属性, 还要加上一个计算属性:
<!-- 父组件 -->
<ComponentDemo v-model="name"></ComponentDemo>
<!-- 子组件 -->
<script setup>
import { computed } from 'vue'
const props = defineProps(['modelValue'])
const emits = defineEmits(['update:modelValue'])
const name = computed({
get() {
return props.modelValue
},
set(newVal) {
emits('update:modelValue', newVal)
}
})
</script>
defineModel宏
VUE3.4为我们提供了新的definemodel宏, 如果使用defineModel, 那一行js代码就可以实现上面的功能
<script setup>
const name = defineModel()
</script>
-
defineModel是一个便利宏, 源码中是使用customRef和watchSyncEffect实现的 -
使用
defineModel先决条件<script setup>vue3.4+
defineModel 的更多语法
双向绑定多个属性时可以指定参数名
<!-- 父组件 -->
<ComponentDemo v-model:age="age" v-model:isActive="isActive"></ComponentDemo>
<!-- 子组件 -->
<script setup>
const age = defineModel('age')
const isActive = defineModel('isActive')
</script>
约束prop参数可以在 model 名称之后传递额外的 prop 选项
<!-- 父组件 -->
<ComponentDemo v-model:isActive="isActive"></ComponentDemo>
<!-- 子组件 -->
<script setup>
const isActive = defineModel('isActive', { required: false, type: Boolean, default: false })
</script>
处理 v-model 修饰符
当存在修饰符时,我们可能需要在读取或将其同步回父组件时对其值进行转换。我们可以通过使用 get 和 set 转换器选项来实现这一点
<!-- 父组件 -->
<ComponentDemo v-model="name"></ComponentDemo>
<!-- 子组件 -->
<script setup>
const [name, modifiers] = defineModel('name', {
required: true,
type: String,
// 配合修饰符使用
set: (val) => {
let newVal = val
if (modifiers.toLowerCase) {
newVal = newVal.toLowerCase()
}
if (modifiers.capitalize) {
newVal = newVal.charAt(0).toUpperCase() + newVal.slice(1)
}
return newVal
}
})
</script>
总结
本文介绍了v-module 双向绑定的原理, 以及如何在组价上使用双向绑定
相比于之前的语法, defineModel大大简化了自定义组件数据通信的代码
如果项目使用 Vue 3.4+ , 更推荐使用defineModel宏实现自定义组件双向绑定