向数组中push,不会出发watch更新
setup() {
let state = reactive({
list: []
})
watch(
() => state.list,
(val) => {
console.log(val)
}
)
state.list.push(1) // 不会触发watch,不知道vue为什么这么做
state.list = [1] // 重新赋值,会触发watch
}
template 可以不再需要顶层节点
<template>
<Header/>
<Footer/>
</template>
teleport把节点挂载到指定id下
<teleport to="#endofbody">
<div class="modal">
hello world
</div>
</teleport>
Suspense组件,展示加载状态
<Suspense>
<template >
<!-- 异步组件 -->
<Suspended-component />
</template>
<template #fallback>
<!-- 异步组件加载完毕前展示的内容 -->
Loading...
</template>
</Suspense>
升级指南
键盘绑定keycode无效,绑定别名有效
<!-- 无效 -->
<input v-on:keyup.13="submit" />
<!-- 有效 -->
<input v-on:keyup.enter="submit" />
移除on off 和 $once方法,使用mitt代替
filters被移除,使用methods或者computed代替
全局api调用方式改变
import Vue from 'vue'
Vue.mixin()
Vue.use()
import { createApp } from 'vue'
const app = createApp({})
app.mixin()
app.use()
setup 中可以实现之前的所有逻辑
setup() {
onMounted(() => {
console.log(333)
})
}
全局属性挂载方法改变
// old
Vue.prototype.http = functuin() {}
// new
app.config.globalProperties.http = function(){}
this.http
render 方法修改
// old
render(h) {
return h('div')
}
// new
import { h} from 'vue'
render() {
return h('div')
}
data必须是一个函数
data() {
return {}
}
支持定义异步组件
import { defineAsyncComponent } from 'vue'
// one
const asyncPageWithOptions = defineAsyncComponent({
loader: () => import('./NextPage.vue'),
delay: 200,
timeout: 3000,
error: ErrorComponent,
loading: LoadingComponent
})
// two
const asyncComponent = defineAsyncComponent(
() =>
new Promise((resolve, reject) => {
/* ... */
})
)
使用非html元素的标签
app.config.isCustomElement = tag => tag === 'plastic-button'
在普通元素上使用is被v-is代替,component组件上仍然可以使用is
<button v-is="plastic-button">Click Me!</button>
<component is="plastic-button"></component>
this.\(scopedSlots将会被移除,统一替代成this.\)slots
// old
h(LayoutComponent, [
h('div', { slot: 'header' }, this.header),
h('div', { slot: 'content' }, this.content)
])
this.$scopedSlots.header
// new
h(LayoutComponent, {}, {
header: () => h('div', this.header),
content: () => h('div', this.content)
})
this.$slots.header
指令生命周期修改
Vue.directive('highlight', {
beforeMount(el, binding, vnode) { // 对应bind
el.style.background = binding.value
},
mounted() {}, // 对应inserted
beforeUpdate() {}, // 新增
updated() {}, // 对应update
beforeUnmount() {}, // 新增
unmounted() {} // 对应unbind
})
watch方法,不再支持通过.进行监听。包括 this.$watch 监听
watch: {
// watch vm.e.f's value: {g: 5}
'e.f': function (val, oldVal) { /* ... */ }
}
vue-router 4的新功能
// 守卫不再需要next,并且支持async
router.beforeEach(async (to, from) => {
// canUserAccess() returns `true` or `false`
return await canUserAccess(to)
})