v-model的变化
vue2有两种方式实现双向数据绑定,一种是v-model
一种是 .sync
(第二种是自定义组件中实现props双向数据绑定),在vue3中,去掉啦 .sync
修饰符,只需要使用v-model
进行双向数据绑定。
为了让v-model
更好的针对多个属性进行双向绑定,vue3
作出了以下修改
绑定属性名的变化
当对自定义组件使用v-model
指令时,绑定的属性名由原来的value
变为modelValue
,事件名由原来的input
变为update:modelValue
<!-- vue2 -->
<ChildComponent :value="pageTitle" @input="pageTitle = $event" />
<!-- 简写为 -->
<ChildComponent v-model="pageTitle" />
<!-- vue3 -->
<ChildComponent
:modelValue="pageTitle"
@update:modelValue="pageTitle = $event"
/>
<!-- 简写为 -->
<ChildComponent v-model="pageTitle" />
去掉了.sync
修饰符,它原本的功能由v-model
的参数替代
<!-- vue2 -->
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
<!-- 简写为 -->
<ChildComponent :title.sync="pageTitle" />
<!-- vue3 -->
<ChildComponent :title="pageTitle" @update:title="pageTitle = $event" />
<!-- 简写为 -->
<ChildComponent v-model:title="pageTitle" />
可以绑定多个v-model
<check-editor
v-for="item in products"
:key="item.id"
v-model="item.sell" // 绑定默认的
v-model:title.trim="item.title"
></check-editor>
允许自定义 v-model
的修饰符 vue2无此功能
示例
export default {
props: {
title: String,
/** 接收自定修饰符*/
titleModifiers: {
default: () => ({}),
}
},
setup(props, context) {
/**输入框修改事件 */
const handleInput = (e) => {
let value = e.target.value;
if(props.titleModifiers.trim) {
value = value.trim()
}
context.emit('update:title', value);
};
return {
handleInput,
};
},
};
v-if 和v-for的变化
vue2 中
<div v-for="item in data" :key="item.id" v-if="是否显示"></div>
在vue2中之所以不建议使用这种方式,是因为 v-for
的优先级会比 v-if
的高,故会先遍历后才会·v-if
当不显示时又会触发响应式数据,这样的效率会很慢
在vue3中
v-if
的优先级会比 v-for
的高,会优先进行 v-if
,故会先进行 v-if
之后才会以进行v-for
但是依旧不推荐上面的那种写法
推荐使用计算属性,使用v-for
遍历需要的数据(数据是通过计算属性筛选出来的)
key
当使用<template>
进行v-for
循环时,需要把key
值放到<template>
中,而不是它的子元素中
在 Vue 2.x 中 <template>
标签不能拥有 key
。不过你可以为其每个子节点分别设置 key
。
<!-- Vue 2.x -->
<template v-for="item in list">
<div :key="item.id">...</div>
<span :key="item.id">...</span>
</template>
在 Vue 3.x 中 key
则应该被设置在 <template>
标签上。
<!-- Vue 3.x -->
<template v-for="item in list" :key="item.id">
<div>...</div>
<span>...</span>
</template>
类似地,当使用 <template v-for>
时存在使用 v-if
的子节点,key
应改为设置在 <template>
标签上。
<!-- Vue 2.x -->
<template v-for="item in list">
<div v-if="item.isVisible" :key="item.id">...</div>
<span v-else :key="item.id">...</span>
</template>
<!-- Vue 3.x -->
<template v-for="item in list" :key="item.id">
<div v-if="item.isVisible">...</div>
<span v-else>...</span>
</template>
当使用v-if v-else-if v-else
分支的时候,不再需要指定key
值,因为vue3
会自动给予每个分支一个唯一的key
Vue 2.x 建议在 v-if
/v-else
/v-else-if
的分支中使用 key
。
<!-- Vue 2.x -->
<div v-if="condition" key="yes">Yes</div>
<div v-else key="no">No</div>
这个示例在 Vue 3.x 中仍能正常工作。但是我们不再建议在 v-if
/v-else
/v-else-if
的分支中继续使用 key
attribute,因为没有为条件分支提供 key
时,也会自动生成唯一的 key
。
<!-- Vue 3.x -->
<div v-if="condition">Yes</div>
<div v-else>No</div>
非兼容变更体现在如果你手动提供了 key
,那么每个分支都必须使用一个唯一的 key
。因此大多数情况下都不需要设置这些 key
。
<!-- Vue 2.x -->
<div v-if="condition" key="a">Yes</div>
<div v-else key="a">No</div>
<!-- Vue 3.x (recommended solution: remove keys) -->
<div v-if="condition">Yes</div>
<div v-else>No</div>
<!-- Vue 3.x (alternate solution: make sure the keys are always unique) -->
<div v-if="condition" key="a">Yes</div>
<div v-else key="b">No</div>
即便要手工给予key
值,也必须给予每个分支唯一的key
,不能因为要重用分支而给予相同的 key
**示例:
<div>
<div v-if="isAccount" >
<label>账号:</label>
<input type="text" />
</div>
<div v-else >
<label>手机号:</label>
<input type="text" />
</div>
<button @click="isAccount = !isAccount">切换登录方式</button>
</div>
Fragment
vue3
现在允许组件出现多个根节点
**