Vue3的v-model区别:
1. `v-model`prop 和事件默认名称已更改:
* prop:`value`->`modelValue`;
* 事件:`input`\->`update:modelValue`;
2. * **移除**`.sync`修饰符和组件的`model`选项
3. * **新增**:现在可以在同一个组件上使用多个`v-model`绑定;
4. * **新增**:现在可以自定义`v-model`修饰符。
>[info] 在 Vue2 中,在组件上使用`v-model`相当于绑定`value`prop 并触发`input`事件:
~~~
<ChildComponent v-model="pageTitle" />
//以下是简写:
<ChildComponent :value="pageTitle" @input="pageTitle = $event" />
~~~
>[info] 在 vue3 中,自定义组件上的`v-model`相当于传递了`modelValue`prop 并接收抛出的`update:modelValue`事件:
~~~
<ChildComponent v-model="pageTitle" />
//以下是简写:
<ChildComponent
:modelValue="pageTitle"
@update:modelValue="pageTitle = $event"
/>
~~~
## `v-model`参数
若需要更改`model`的名称,现在我们可以为`v-model`传递一个*参数*,以作为组件内`model`选项的替代:
~~~
<ChildComponent v-model:title="pageTitle" />
//以下是简写:
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
~~~
## 允许同时使用多个`v-model`
~~~
<ChildComponent v-model:title="pageTitle" v-model:content="pageContent" />
//以下是简写:
<ChildComponent
:title="pageTitle"
@update:title="pageTitle = $event"
:content="pageContent"
@update:content="pageContent = $event"
/>
~~~
## `v-model`自定义修饰符
除了像`.trim`这样的 vue2 硬编码的`v-model`修饰符外,现在 vue3 还支持自定义修饰符:
~~~
<ChildComponent v-model.capitalize="pageTitle" />
~~~
### 创建自定义修饰符`capitalize`案例:
自定义修饰符会通过`modelModifiers`传递给组件prop。在组件的`created`生命周期中`modelModifiers`会包含自定义修饰符`capitalize`,且值为true。
~~~
//capitalize是自定义修饰符
<my-component v-model.capitalize="myText"></my-component
~~~
~~~
app.component('my-component', {
props: {
modelValue: String,
//传递的自定义修饰符会在这个prop中
modelModifiers: {
default: () => ({})
}
},
emits: ['update:modelValue'],
template: `
<input type="text"
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)">
`,
created() {
//获取传递的自定义修饰符
console.log(this.modelModifiers) // { capitalize: true }
}
})
~~~
### 对于带参数的`v-model`绑定,生成的 prop 名称将为`arg + "Modifiers"`:
~~~
<my-component v-model:description.capitalize="myText"></my-component>
~~~
~~~
app.component('my-component', {
//v-model:description.capitalize descriptionModifiers 是自定义修饰符接收参数
props: ['description', 'descriptionModifiers'],
emits: ['update:description'],
template: `
<input type="text"
:value="description"
@input="$emit('update:description', $event.target.value)">
`,
created() {
console.log(this.descriptionModifiers) // { capitalize: true }
}
})
~~~
### 实现自定义修饰符`capitalize`的功能,给输入的值第一个变大写:
~~~
<div id="app">
<my-component v-model.capitalize="myText"></my-component>
{{ myText }}
</div>
const app = Vue.createApp({
data() {
return {
myText: ''
}
}
})
app.component('my-component', {
props: {
modelValue: String,
modelModifiers: {
default: () => ({})
}
},
emits: ['update:modelValue'],
methods: {
emitValue(e) {
let value = e.target.value
//如果传递了capitalize修饰符,处理值第一个变为大写
if (this.modelModifiers.capitalize) {
value = value.charAt(0).toUpperCase() + value.slice(1)
}
this.$emit('update:modelValue', value)
}
},
template: `<input
type="text"
:value="modelValue"
@input="emitValue">`
})
app.mount('#app')
~~~