Vue3 v-model非兼容更改

简单概述

非兼容更改:

  • 用于自定义组件时, v-model prop和事件默认名称已更改:
    • prop : value -> modelValue
    • 事件: input -> update: modelValue;
  • v-bind 的 .sync 修饰符和组件的 model 选项已移除,可在 v-model 上加一个参数代替

新增:

  • 现在可以在同一个组件上使用多个 v-model 绑定;
  • 现在可以自定义 v-mdoel 修饰符;

接下来一一介绍

2.x语法

在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" />

3.x语法

双向数据绑定的API已经标准化,以减少开发者在使用 v-model 指令时的混淆,更加灵活

自定义组件上的 v-model 相当于 modelValue prop 并接收抛出的 update: mdoelValue 事件:

<ChildCompoent v-model="pageTitle" />

// 简写前为:
<ChildCompoent
	:modelValue="pageTitle"
    @update: modelValue="pageTitle = $event"
/>

v-model参数

若需要更改 model 的名称,我们现在可以为 v-model 传递一个参数,以作为组件内 model 选项的替代:

<ChildComponent
  v-model:title="pageTitle"
/>
<!-- title指的是 Prop Name -->
<!-- pageTitle指的是  Data to bind -->

<!-- 未简写前 -->
<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" />
  • 对于所有不带参数的 v-model ,确保分别将 prop 和 event 命名更改为 modelValueupdate: 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高级用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@乐知者@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值