前言
这次Vue 3的v-model解决了从前Vue 2的v-model的很多痛点,可以说是一次很舒服的升级,一起看看。
官方文档:https://v3.cn.vuejs.org/guide/component-custom-events.html#v-model-参数
官方升级指南:https://v3.cn.vuejs.org/guide/migration/v-model.html
简单用法
用于自定义组件时,v-model的prop和事件默认名称已更改:
prop:value -> modelValue
event:input -> update:modelValue
即:
<xxComponent v-model="varA" />
等价于:
<xxComponent :modelValue="varA" @update:modealValue="varA = $event" />
多个v-model指令
<xxComponent v-model.varA="varA" v-model.varB="varB" />
等价于:
<xxComponent :varA="varA" @update:varA="varA = $event" :varB="varB" @update:varB="varB = $event" />
修饰符
- 支持Vue 2的所有修饰符:
- 支持自定义修饰符
现在的例子是:自定义prop名+自定义修饰符:
父组件:
核心就一句:v-model:content.camelCase="word"
,其中content
是子组件要求的prop名,要听子组件的规定。word
是父组件的变量名,叫什么名无所谓。camelCase
也是子组件要求的修饰符名,要听子组件的规定。
<template>
<div>
<zi v-model:content.camelCase="word" />
</div>
</template>
<script>
import zi from "./zi.vue";
export default {
components: {
zi,
},
data() {
return {
word: "",
};
},
};
</script>
子组件:
子组件较复杂,而且我特意用组合式API来演示。
<template>不说了。
defineProps
函数的写法就是这样,先写content
,然后写contentModifiers
,这是Vue的规定,必须是prop名跟Modifiers
字串。contentModifiers
的值必须是这样一个函数。
useContext
和getCurrentInstance
在开发中会经常用到。useContext()能拿到几个变量,包括props变量。getCurrentInstance()能拿到组件实例this,用来执行.emit()。
content
必须是计算变量,否则传入prop新值之后,子组件无法感知。
emitCamelCase
方法里,if语句是为了确认修饰符正确。
instance.emit
语句没什么可说的。
<template>
<div>
<input type="text" :value="content" @input="emitCamelCase" />
</div>
</template>
<script setup>
import { useContext, getCurrentInstance, defineProps, computed } from "vue";
defineProps({
content: String,
contentModifiers: {
default: () => ({}),
},
});
const ctx = useContext();
const instance = getCurrentInstance();
let content = computed(() => ctx.props.content);
function emitCamelCase(e) {
if (ctx.props.contentModifiers.camelCase) {
instance.emit(
"update:content",
e.target.value.replace(/_./g, (a) => {
return a[1].toUpperCase();
})
);
}
}
</script>
如果有多个v-model,就多来一份代码就可以了。