文章目录
vue3主要升级了哪些
- createApp
- emits属性
- 生命周期
- 多事件(模板标签可同时绑定多个事件)
- Fragment(模板根节点可以多个,但个人不建议,2021年测试对与其他库的兼容不好)
- 移除.sync
- 异步组件的写法
- 移除filter
- Teleport
- Suspense
- Composition API
平时用不到vue3开发的可能不能影响深刻的记住,只能私下多用了。
概括vue3比vue2提升在哪里
- 性能更好,更快
下面的标题内容里会具体说说 - 更好的响应式
proxy代理代替了definedProperty,无响应式丢失缺陷,且无需深度递归 - 打包体积更小
用了tree-shaking等技术使得打包体积更小 - ts的支持
vue3本身就是用ts重写的,对ts的支持就很友好啦 - 更好的代码组织
composition api的加入,使得逻辑代码更好组织 - 更好的逻辑抽离
可以把使用了composition api公共逻辑部分抽离成hook - 更多新功能
上面有介绍
vue3为何比vue2快
主要使用了如下技术变快
- proxy的按需递归
- PatchFlag
- hoistStatic
- cacheHandler
- SSR优化
- tree-shaking
- vite
以下部分解释带有课程标记的来自慕课网课程,尽量能用大白话讲明白,不用看源码增加心智负担
proxy的按需递归
es5的Object.defineProperty对一个多维对象必须递归处理。而proxy一个特点就是,proxy要触发get才能被处理成proxy对象,也就是不需要像defineProperty一样,一上来就给变量一条龙服务,而是按需递归。
也有另一种说法说proxy是对整个变量进行监听,没有按需递归,根本不需要递归。
PatchFlag
编译模板时,会给节点做标记。标记可分为不同的类型,例如普通静态文字,动态props变量展示、动态id属性、动态class属性等等。
diff算法时,通过编译阶段的标记,可以区分静态节点,以及不同类型的动态节点。这样打了静态文字的节点就不比较了,只会去比较动态节点。
在vue2时期没有标记,每个节点都要参与新旧比较。
具体看6-19课
补充:3的diff算法除了用PatchFlag外,还把子节点的更新从2的双端比较又增加了“最长递增子序列”, 还增加了静态提升,函数提升等。3的diff算法就比2快了很多。
hoistStatic
也叫静态节点提升。
将静态节点的定义,提升到父作用域,缓存起来。多个相邻的静态节点,会被合并起来缓存。
下次渲染的时候就不用重复创建元素,直接复用。典型的拿空间换时间的优化策略。
加上上面描述的静态节点标记,简直如虎添翼。
具体看6-20课
CacheHandler
也叫函数提升
缓存事件,等下次节点重新编译的时候就直接挂上去,不用重新定义了
具体看6-20课
SSR
静态文字节点直接输出字符串,不用转换成vdom对象
tree-shaking
在vue2时,我们写的每个vue组件都是单例的,使用的api都是需要通过vue实例去调用,例如this.$nextTick
、data、computed等。这样,打包的时候无法确定这个实例上有哪些api是用到的,都一股脑打包了。
而在vue3中,我们使用的vue api都是通过模块按需引入的方式,例如:
import { nextTick } from 'vue'
nextTick(() => {})
打包的时候就能知道哪些api使用到了,需要打包,没使用到的就不打包删掉。这也是得益于ES6 Module的静态编译思想,编译的时候就能知道依赖关系
vite启动快
具体6-22、6.23,总的来说就是通过Module引入的写法,就已经是webpack打包之后的样子了。而且Module可以实现按需引入js模块。
下面细讲
vue3的hooks是什么
使用react的开发者应该就理解:
- 抽离逻辑代码到一个函数
- 函数命名约定为useXXX格式
- 在setup中引用useXXX函数
vite
vite是一个很快的构建工具,webpack在开发环境中,也是要打包一遍,然后把打包好后的代码给dev server运行的,项目复杂依赖多了就会越来越卡。
vite解决了webpack两个痛点:开发环境中,启动时间快,热更新快。
原理
从几个方面去讲
代码运行:浏览器原生支持ES Module的编译,可以直接运行开发环境中符合es module规范的源码。
引用关系:如果源码中有import的引用关系,也只是向dev server发送请求,服务器简单处理一下就把对应源码给浏览器运行,省去了打包的过程。且不是一次性把整个项目的mport关系获取编译,而是按需加载。
热更新:某个模块代码更新时,只需要重新引入直接运行即可。
依赖处理:之前的依赖编译器是由node.js编写的,性能不行。vite中用的是go编写的esbuild编译器,能够快速处理依赖。esbuild能够把还用commonjs规范写的依赖转成esm规范。对于依赖代码也会用http的强缓存做缓存,对于业务代码用协商缓存做处理。
可能这样说还是会有点迷茫,举例说明下:
在webpack打包出来的html文件是这样的:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./js/main.js"></script>
</body>
</html>
main.js文件中没有其他文件的引入关系,每次修改都要重新生成一个容量大大的main.js文件(因为不支持import、export语法)。
而使用了es Module规范后,script的标签就变成:
<script src="./js/main.js" type="module"></script>
这时候main.js里代码就可以直接执行import、export代码,main.js里的代码可以分散成很多个小的js文件,再引入到main.js里,修改其中一个小的导出文件,只需要更新对应的哪个小的js文件即可。
缺点
生产环境因为并不是所有浏览器都支持ES Module,所以使用Rollup工具去做的打包,并不会快很多。且打包的代码和开发代码肯定不一样。