- Vue3:两年开发,99位贡献者,2600次提交,628次PR
- Vue3支持2的大多数特性
- 官网: v3.vuejs.org
- 性能提升:
- 打包大小减少41%
- 初次渲染快55%,更新快133%
- 内存使用减少54%
- Composition API(API合集)
- ref和reactive
- computed和watch
- 新的生命周期函数
- 自定义函数-Hooks函数
- 其他新增特性
- Teleport-瞬移组件的位置
- Suspense-异步加载组件的新福音
- 全局API的修改和优化
- 更多的试验性特性
- 更好的Typescript支持
- 随着功能的增长,复杂组件的代码变得难以维护、随着复杂度的上升、带来的问题。 例:List筛选&分页:分散到多个地方=>Mixin
- Mixin的缺点
- 命名冲突
- 不清楚暴露出来变量的作用
- 重用到其他component经常会遇到的问题
- Vue2对于typescript的支持非常有限
- 全局安装脚手架
npm install -g @vue/cli
确认是否成功安装
vue --version
- 快速创建脚手架
vue create vue3-basic
- 图形化界面
vue ui
访问 http://localhost:8000 即可
pnpm install
pnpm run serve
pnpm run build
pnpm run lint
暴露一系列钩子供开发者操作
每个主要Vue生命周期事件被分成两个钩子,分别在事件之前和之后调用。Vue应用程序中有4个主要事件(8个主要钩子)。
beforeCreate
: 在实例初始化之后,数据观测 (data observation) 和 event/watcher 事件配置之前被调用。created
: 在实例创建完成后被立即调用。实例已完成以下的配置:数据观测 (data observation),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。
beforeMount
: 在挂载开始之前被调用:相关的 render 函数首次被调用。mounted
:el
被新创建的vm.$el
替换,并挂载到实例上去之后调用该钩子。
beforeUpdate
: 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。updated
: 由于数据更改导致的虚拟 DOM 重新渲染和打补丁后调用。
beforeDestroy
: 在实例销毁之前调用。在这一步,实例仍然完全可用。destroyed
: 在实例销毁之后调用。该钩子被调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
- 新建Vue实例
new Vue()
- 初始化事件&生命周期:
setup
方法beforeCreate
created
- 初始化注入&校验
- 是否指定“el”(元素)选项
- 否:当调用
vm.$mount(el)
函数时 - 是:是否指定“template”(模板)选项
- 是:将
template
编译到render
函数中(渲染) - 否:将
el
外部的HTML作为template
编译
- 是:将
beforeMount
- 否:当调用
- 创建
vm.$el
并用其替换“el”mounted
- 挂载完毕
- 当响应式数据
data
被修改时->beforeUpdate
- 虚拟DOM重新渲染并应用更新
updated
- 当响应式数据
- 当调用
vm.$destroy()
函数时- 卸载
beforeDestroy
->beforeUnmount
- 卸载
- 解除绑定:销毁子组件以及事件监听器
- 销毁完毕
destroyed
->unmounted
onMounted()
: 注册一个回调函数,在组件挂载完成之后执行。onUpdated()
: 注册一个回调函数,在组件因为响应式状态变更而更新其DOM树之后停用。onUnmounted()
: 注册一个回调函数,在组件实例被卸载之后调用。onBeforeMount()
: 注册一个钩子,在组件被挂在之前被调用。onBeforeUpdate()
: 注册一个钩子,在组件即将因为响应式状态变更而更新其DOM树之前被调用。onBeforeUnmount()
: 注册一个钩子,在组件实例被卸载之前调用。onErrorCaptured()
: 注册一个钩子,在捕获了后代组件传递的错误时调用。onRenderTracked()
: 注册一个调试钩子,当组件渲染过程中追踪到响应式依赖时调用。onRenderTriggered()
: 注册一个调试钩子,当响应式依赖的变更触发了组件渲染时调用。onActivated()
: 注册一个回调函数,若组件实例是<KeepAlive>
缓存树的一部分,当组件被插入到DOM中时被调用。onDeactivated()
: 注册一个回调函数,若组件实例是<KeepAlive>
缓存树的一部分,当组件从DOM被一处时调用。onServerPrefetch()
: 注册一个异步函数,在组件实例在服务器上被渲染之前调用。
beforeCreate
-> 使用setup()
created
-> 使用setup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeDestroy
->onBeforeUnmount
destroyed
->onUnmounted
activated
->onActivated
deactivated
->onDeactivated
errorCaptured
->onErrorCaptured
onRenderTracked
onRenderTriggered
使用CompositionAPI解决:
- 相关feature结合在一起
- 更高灵活度
-
鼠标追踪器
- 捕捉当前鼠标坐标
-
网页状态加载 实现异步请求Axios
// Make a request for a user with a given ID axios.get('/user?ID=12345') .then(function (response) { // handle success console.log(response); }) .catch(function (error) { // handle error console.log(error); }) .finally(function () { // always executed });
https://dog.ceo/dog-api/获取狗狗图片
模块化结合typescript-泛型改造
<T | null>
发送任意种类的异步请求
新的方法来定义Component
使用defineComponent
包裹,对传入对象有了新的方法
组件渲染时需显示全局对话窗:传统方式包括组件 Frame
- Dialog被包裹在其他组件之中容易被干扰
- 样式也在其他组件中,容易变得混乱
渲染在顶层另外一个DOM组件上 Frame Teleport包裹
优化全局提示框 Frame 打开关闭&slot实现自定义内容
内置组件:异步请求 要使用Suspense,要返回一个promise 使用异步请求展示个性化的定制
<template>
<h1>{{result}}</h1>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
setup() {
// 由于return异步可以用Suspense处理
return new Promise((resolve) => {
setTimeout(() => {
// 三秒后返回
return resolve({
result: 42
})
}, 3000)
})
},
})
</script>
语法糖:async
包裹
<template>
<img :src="result && result.message">
</template>
<script>
import { defineComponent } from 'vue'
export default defineComponent({
async setup() {
const rawData = await axios.get('https://dog.ceo/api/breeds/image/random')
return {
result: rawData.data
}
},
})
</script>
抓取Suspense错误 on即可在setup()使用
main.ts采用一个API:CreateApp创建一个对象并且挂载到节点
import { createApp } from 'vue'
import App from './App.vue'
// 创建App的实例并绑定在DOM节点上
createApp(App).mount('#app')
config.productionTip 被删除 config.ignoredElements改名为config.isCustomElement config.keyCodes 被删除
Vue.component -> app.component Vue.directive -> app.directive
Vue.mixin -> app.mixin Vue.use -> app.use