Vue3.0

Vue3和Vue2的区别

一.源码组织方式的改变

1.代码全部用Typescript重写
2.使用Monorepo的方式来管理源代码,使用一个项目来管理不同的包,把不同功能的代码放到不同的package中管理。这样的话每个功能模块划分都很明确,模块之间的依赖关系也很明确,并且每个功能模块都能单独发布测试和使用.

二.性能提升

1.响应式系统的升级

Vue2响应式系统

在数据初始化的时候会遍历data中的所有的成员通过defineProperty把对象的属性转化为getter和setter,如果对象的属性又是对象的话需要递归处理每一个子对象.
问题:

  • 因为是在初始化进行,即便是不需要使用的对象也进行了响应式处理,浪费了性能
  • 虽然Object.defineProperty()是可以对数组实现监听操作的,但是vue并没有实现这个功能,因为数组长度不定而且数据可能会很多,如果对每一个数据都实现监听,性能代价太大
  • Object.defineProperty()针对的是对象的某个属性,而且这个操作在vue的初始化阶段就完成了,所以新增的属性无法监听
Vue3响应式系统

Vue3中使用Proxy对象重写了响应式系统,提升了响应式系统的性能和功能.

  • 可以监听动态新增的属性
  • 可以监听删除的属性
  • 可以监听数组的索引和length的属性
    所以不需要在初始化去递归处理每一个属性,另外如果有多个属性嵌套的话,只有访问某个属性的时候才会递归处理下一级的属性.

2.编译优化

-静态节点:<div>12<div>,内容是固定的
-动态节点:<div :id='id'>{{count}}</div>,内容是动态获取的

Vue2

在Vue2中,重新的渲染的时候会重新去创建新旧Vnode,diff的时候会跳过静态根节点,对比剩下的每一个vnode,哪怕这些节点什么都没做

Vue3

标记和提升所有的静态节点,diff的时候只需要对比动态节点内容

import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
//-- 静态节点提升 start  --
const _hoisted_1 = /*#__PURE__*/_createElementVNode("div", null, "静态节点", -1 /* HOISTED */)
const _hoisted_2 = ["id"]
const _hoisted_3 = ["onClick"]
//-- 静态节点提升 end  -- 
export function render(_ctx, _cache, $props, $setup, $data, $options) {
	//没有根节点元素会传入 _Fragment,也就是自动帮我们创建一个根节点元素
  return (_openBlock(), _createElementBlock(_Fragment, null, [
    _hoisted_1,
    _createElementVNode("div", null, _toDisplayString(_ctx.count), 1 /* TEXT */),
    _createElementVNode("div", { id: _ctx.id }, "id", 8 /* PROPS */, _hoisted_2),
    _createElementVNode("button", { onClick: _ctx.dot }, "button", 8 /* PROPS */, _hoisted_3)
  ], 64 /* STABLE_FRAGMENT */))
}
/ **
例一:  _createElementVNode("div", null, _toDisplayString(_ctx.count), 1 /* TEXT */)
创建一个虚拟节点,标签类型为div,属性空,内容动态渲染,   1 是patch flag,代表文本内容是动态绑定的
例二:  _createElementVNode("div", { id: _ctx.id }, "id", 8 /* PROPS */, _hoisted_2)
创建一个虚拟节点,标签类型为div,属性id动态渲染, 文本内容id,  8 是patch flag,代表属性是动态绑定的,_hoisted_2其实就是 ["id"],说明动态绑定的是哪些属性

将来在diff的时候,会检测整个block里面带patch flag的标记的节点,静态节点会直接跳过.而且在比较动态节点的时候,会根据patch flag的值去进行比较,如例二中的     8 /* PROPS */,  ["id"]     ,那么它只会比较这个节点中,属性id的值,降低了性能损耗
**/

我们再去勾选上otions的cacheHandlers,对比变化的代码,
没有事件缓存的:

 const _hoisted_3 = ["onClick"] 
 _createElementVNode("button", { onClick: _ctx.dot }, "button", 8 /* PROPS */, _hoisted_3)

事件缓存的:

 _createElementVNode("button", {
      onClick: _cache[0] || (_cache[0] = (...args) => (_ctx.dot && _ctx.dot(...args)))
    }, "button")
//没有开启缓存,绑定事件行为会被认为是动态绑定,每次都去追踪变化;开启缓存后,下次diff直接使用,不追踪变化      

三.优化打包体积

  • Vue3.0中移除了一些不常用的API
    • 例如:inline-template,filter等
  • Tree-shaking
    • Vue3中内置的组件和指令以及一些新增的API都是按需引入的,如果你没有使用就不会被打包进去

Vite

Vite vs Vue-CLI

  • Vite在开发模式下不需要打包可以直接运行
    • 使用浏览器原生支持的ES Module加载模块也就是通过import来导入模块,浏览器通过<script type='module'>加载模块代码
    • Vue会开启一个测试服务器,会拦截浏览器发起的请求,浏览器会发起请求获取相应的模块,Vite会对浏览器不识别的模块进行处理,例如请求.vue结尾的文件的时候,会在服务器上对文件进行编译,把编译的结果返回给浏览器.
  • Vue-CLI开发模式下必须要对项目打包才可以运行

Vite特点

1.快速冷启动

因为不需要打包,所以可以快速冷启动

2.按需编译

代码是按需编译的,因此只有当代码在当前需要加载的时候才会编译,你不需要在开启开发服务器的时候等待项目被打包,当项目比较大的时候会更明显

3.模块热更新

vite支持模块热更新,并且模块热更新的性能与模块总数无关,无论你有多少模块,html的速度始终很快

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值