非兼容更改:
v-model prop和事件默认名称已更改:
新增:
接下来一一介绍
在Vue2组件中,使用 v-model 指令必须使用名为 value 的prop。如果不使用这个,必须 使用 v-bind.sync ,此外,由于 v-model 和 value 之间的这种硬编码关系,产生如何处理原生元素和自定义元素的问题
后来,在Vue2.2中引入了 model 组件选项,允许组件自定义用于 v-model 的prop和事件。但是,这里只允许在组件上使用一个 v-model
<childComponent v-model="pageTitle"/>
// 在组件上使用 v-model 相当于绑定 value prop 并触发 input 事件
<childComponent :value="pageTitle" @input="pageTitle = $event"/>
如果这时想要更改 prop 或事件名称,则需要在 ChildCompoent 组件中添加 model 选项:
// 在 childComponent 父组件内写
<childCompoent v-model="pageTitle">
// 在 childCompoent 组件内部写
export default {
model: {
prop: 'title',
event: 'change'
},
props: {
// 允许 value 属性用于其他用途
value: String,
// 用 title 代替 value 作为 model 的 prop
title: {
type: String,
default: 'title'
}
}
}
这样简写为:
<ChildCompoent :title="pageTitle" @change="pageTitle = $event">
v-bind.sync在某些情况下,我们可能需要对某一个Prop进行 双向绑定(除了前面的 v-model 绑定 prop的情况)
推荐使用 update: myPropName 抛出事件。例如:对于上面案例中带有 title prop 的 ChildComponent ,我们可以通过下面的方式将分配新 value 的意图传达给父级:
this.$emit('update: title', newValue);
在父组件可以监听这个事件,并更新到本地的 data property :
<ChildComponent :title="pageTitle" @update: title = "pageTitle = $event" />
两个使用 .sync 修饰符缩写形式为:
<ChildCompoent :title.sync="pageTitle" />
双向数据绑定的API已经标准化,以减少开发者在使用 v-model 指令时的混淆,更加灵活
自定义组件上的 v-model 相当于 modelValue prop 并接收抛出的 update: mdoelValue 事件:
<ChildCompoent v-model="pageTitle" />
// 简写前为:
<ChildCompoent
:modelValue="pageTitle"
@update: modelValue="pageTitle = $event"
/>
若需要更改 model 的名称,我们现在可以为 v-model 传递一个参数,以作为组件内 model 选项的替代:
<ChildComponent
v-model:title="pageTitle"
/>
<ChildComponent
:title="pageTitle"
@update:title="pageTitle = $event"
/>
可以作为 .sync 修饰符的替代,而且允许我们在自定义组件上使用多个 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 修饰符
Vue还支持自定义修饰符:
<ChildComponent v-model.capotalize="pageTitle" />
Vue2项目迁移到Vue3,所涉及的修改
.sync 部分并将其替换为 v-model :<ChildComponent :title.sync="pageTitle" />
<ChildComponent v-model:title="pageTitle" />
modelValue 和 update: modelValue<ChildComponent v-model="pageTitle" />
// ChildComponent 组件内部
export default {
prop: {
modelValue: String // 以前是 'value: String'
},
emits: ['update: modelValue'],
methods: {
changeTitle(title) {
this.$emit('update: modelValue', title)
// 以前的用法是 'this.$emit('input', title)'
}
}
}
如果需要回味一下 .sync 的用法,这有 入口 .sync高级用法