1、语法上的一些变化
① vue3的template支持多个根标签,vue2不支持
② v-if与v-for的优先级对比 vue2在一个元素上同时使用v-if和v-for时,v-for会优先作用
vue3在一个元素上同时使用v-if和v-for时,v-if会优先作用 ③ v-bind合并行为
<!-- vue2中如果一个元素同时定义了v-bind="object"和一个相同的单独的property,
那么这个单独的property总是会覆盖object中的绑定 -->
<!-- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- result -->
<div id="red"></div>
<!-- vue3则是由声明绑定的顺序决定 -->
<!-- template -->
<div id="red" v-bind="{ id: 'blue' }"></div>
<!-- result -->
<div id="blue"></div>
<!-- template -->
<div v-bind="{ id: 'blue' }" id="red"></div>
<!-- result -->
<div id="red"></div>
④ v-model语法糖机制改变 vue2中v-model在表单元素使用上使用属性和表单事件,是固定不变的
- 只用于表单元素,默认属性名和事件名是
value和input - 硬编码,不能扩展
<comp v-model="msg"></comp>
<!-- 等价于 -->
<comp :value="msg" @input="msg = $event"></comp>
// 示例:自定义input组件
Vue.component('custom-input', {
props: {
value: String,
},
template: `
<input
type="text"
:value="value"
@input="$emit('input', $event.target.value)"
>
`
})
// 示例:自定义count组件
Vue.component('custom-count', {
model: {
prop: 'v', // default: value
event: 'i' // default: input
},
props: {
v: Number
},
data(){
return {
count: this.v
}
},
template: `<button @click="$emit('i', ++count)">+1</button>`
})
vue3中v-model可以使用到任意组件,默认通过modelValue属性和自定义事件实现,不依赖于表单元素事件,且通过传递参数同一组件可以使用多个v-model
- 默认实现不再依赖表单元素事件,可以用于任意组件,默认属性名和事件名是
modelValue和update:modelValue - 通过不同的参数
v-model:foo指定属性名,修改体现在父组件中,同一组件可以绑定多个v-model - 不再依赖.sync修饰符
<custom-input v-model="msg"></custom-input>
<!-- 等价于 -->
<custom-input :model-value="msg" @update:model-value="msg = $event"></custom-input>
<!-- 更改v-model参数 -->
<custom-input v-model:mv="msg"></custom-input>
<custom-count v-model="count"></custom-count>
// 示例1:自定义input组件
// 实现1:默认参数
app.component('custom-input', {
props: ['modelValue'],
template: `
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)"
>
`
})
// 更改参数
app.component('custom-input', {
props: ['mv'],
template: `
<input
:value="mv"
@input="$emit('update:mv', $event.target.value)"
>
`
})
// 实现2:使用input的v-model + computed(计算属性)
app.component('custom-input', {
props: ['modelValue'],
computed: {
value: {
get() {
return this.modelValue;
},
set(v) {
this.$emit('update:modelValue', v);
},
},
},
template: `
<input v-model="value">
`
})
// 示例2:自定义count组件
app.component('custom-count', {
props: {
modelValue: Number,
},
methods: {
increment() {
this.$emit('update:modelValue', ++this.modelValue);
},
decrement() {
this.$emit('update:modelValue', --this.modelValue);
},
},
template: `
<button @click="increment">+1</button> ~
<button @click="decrement">-1</button>
<p>{{modelValue}}</p>
`
})
<!-- 多个v-model绑定 -->
<user-name v-model:first-name="firstName" v-model:last-name="lastName"></user-name>
app.component('user-name', {
props: {
firstName: String,
lastName: String,
},
template: `
<input
type="text"
:value="firstName"
@input="$emit('update:firstName', $event.target.value)">
<input
type="text"
:value="lastName"
@input="$emit('update:lastName', $event.target.value)">
`
})
⑤ v-for中的Ref数组 在vue2中,v-for绑定$refs将会自动生成一个refs的数组,但是在v-for中这种行为将会变得有歧义和不高效。
在vue3中,这种用法不会生效,因为vue3不会自动生成refs的数组。如果我们需要拿到多个refs组成的数组,那么就需要使用函数的方式手动去绑定。
<!-- vue2 -->
<div v-for="(item, index) in [4, 5, 6]" :key="'ref' + index" ref="itemRef">
{{ item }}
</div>
export default {
mounted () {
console.log('ref:', this.$refs.itemRef)
}
}
<!-- vue3 -->
<div v-for="(item, index) in [4, 5, 6]" :key="'ref' + index" :ref="setItemRef">
{{ item }}
</div>
import { onBeforeUpdate, onMounted } from 'vue'
export default {
setup () {
let itemRefs = []
const setItemRef = el => {
itemRefs.push(el)
}
onBeforeUpdate(() => {
itemRefs = []
})
onMounted(() => {
console.log('ref:', itemRefs)
})
return {
itemRefs,
setItemRef
}
}
}
2、生命周期的变化
- setup():开始创建组件之前,在beforeCreate和created之前执行。创建的是data和method
- onBeforeMount():组件挂载到节点上之前执行的函数。
- onMounted():组件挂载完成后执行的函数。
- onBeforeUpdate():组件更新之前执行的函数。
- onUpdated():组件更新完成之后执行的函数。