Vue3.0六大两点
1. Performance:性能比Vue2.x快1.2~2倍
2. Tree shaking support:按需编译,体积比Vue2.x更小
3. Composition API:组合API(类似React Hooks)
4. Better TypeScript support:更好的 Ts 支持
5. Custom Renderer API:暴露了自定义渲染API
6. Fragment,Teleport(Protal),Suspense:更先进的组件
Vue3.0 是如何变快的
diff方法优化
http://vue-next-template-explorer.netlify.app/
1. Vue2 中的虚拟dom是进行全量的对比
2. Vue3 新增了静态标记(PatchFlag)
**PatchFlags标记枚举**
在与上次虚拟节点进行对比时候,只对比带有 patch flag 的节点
并且可以通过 flag 的信息得知当前节点要对比的具体内容
在创建虚拟dom的时候,会根据DOM中的内容会不会发生变化,添加静态标记
export const enum PatchFlags {
// 动态文本节点
TEXT = 1,
// 动态Class的元素
CLASS = 1 << 1, //2
// 动态样式(静态如style="color: red",也会提升至动态)
STYLE = 1 << 2, //4
// 动态属性,但不包含类名和样式
PROPS = 1 << 3, //8
// 动态key的属性,当key改变时,需要进行完整的diff比较
FULL_PROPS = 1 << 4, //16
// 监听事件的节点
HYDRATE_EVENTS = 1 << 5, //32
// 一个不会改变子节点顺序的fragment
STABLE_FRAGMENT = 1 << 6, //64
// 带有key属性的fragment or 部分子节点
KEYED_FRAGMENT = 1 << 7, //128
// 表示带有无key绑定的片段
UNKEYED_FRAGMENT = 1 << 8, //256
// 表示只需要非属性补丁的元素,例如ref或hooks
NEED_PATCH = 1 << 9, //512
// 表示具有动态插槽的元素
DYNAMIC_SLOTS = 1 << 10, //1024
// 静态节点
HOISTED = -1
// 指示在diff过程应该要退出优化模式
BAIL = -2
}
hoistStatic 静态提升
Vue2中无论元素是否参与更新,每次都会重新创建,然后再渲染
const _hoisted_1 = /*#__PURE__*/_createVNode("p", null, "鸡哥", -1 /* HOISTED */)
const _hoisted_2 = /*#__PURE__*/_createVNode("p", null, "鸡哥", -1 /* HOISTED */)
const _hoisted_3 = /*#__PURE__*/_createVNode("p", null, "鸡哥", -1 /* HOISTED */)
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_hoisted_1,
_hoisted_2,
_hoisted_3,
_createVNode("p", null, _toDisplayString(_ctx.msg), 1 /* TEXT */)
]))
}
Vue3中对不参与更新的元素,会做静态提升,只会被创建一次,在渲染时直接复用即可
cacheHandlers 事件侦听缓存
默认情况下 onClick 会被视为动态绑定,所以每次都会去追踪它的变化
但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可
export function render(_ctx, _cache, $props, $setup, $data, $options) {
return (_openBlock(), _createBlock("div", null, [
_createVNode("button", {
onClick: _cache[1] || (_cache[1] = (...args) => (_ctx.onClick(...args)))
}, "按钮")
]))
}
ssr渲染
当有大量静态的内容时候,这些内容会被当做纯字符串推进一个Buffer里面,即使存在动态的绑定,会通过模板插值嵌入进去。这样会比通过虚拟dom来渲染快上很多。
当静态内容达到一定量级时候,会使用_createStaticVNode方法在客户端dom来渲染一个static node,这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染。
什么是 Vite
Vite是Vue作者开发的一款意图取代Webpack的工具
其实现原理是利用 ES6 的 import 会发送请求去加载文件的特性,拦截这些请求,做一些预编译,省去webpack冗长的打包时间
安装Vite
npm install -g create-vite-app
利用Vite创建Vue3项目
create-vite-app 项目名
安装依赖运行项目
npm install npm run dev
setup(){} 组合入口函数 在BeforeCreate:组件和Create之间执行 BeforeCreate:组件刚刚被创建出来,组件的data和methods还没有初始化好 setup:由于在执行setup的时候 还没有执行Create生命周期方法,所以在setup函数中,无法使用data和methods Create:组件刚刚出来,并且组件data和methods初始化好了 Composition API 和 Option API 的混合使用
Option API vue2
Composition API(组合api/注入api)
reactive 函数
什么是 reactive
reactive 是 Vue3 中提供的实现响应式数据的方法
在 Vue2 中响应式数据是通过 defineProperty 来实现的,而在 Vue3 中响应式数据是通过 ES6 的 Proxy 来实现的
reactive 注意点
reactive 参数必须是对象 (json/array)
如果给 reactive 传递了其他对象
默认情况下修改对象,界面不会自动更新
如果想更新,可以通过重新赋值的方式
ref 函数
ref 和 reactive 一样,也是用来实现响应式数据的方法
由于 reactive 必须传递一个对象,所以导致在企业开发中,如果我们只想让某个变量实现响应式的时候会非常麻烦,
所以 Vue3 就给我们提供了 ref 方法,实现对简单值的监听
ref 本质
ref 底层的本质其实还是 reactive,系统会自动根据我们给 ref 传入的值将它转换成 ref(xx) -> reactive({value: xx})
ref 注意点
在 Vue 中使用 ref 的值不用通过 value 获取
在 JS 中使用 ref 的值必须通过 value 获取
ref 和 reactive 的区别
如果在 template 里使用的是 ref 类型的数据,那么 Vue 会自动帮我们添加 .value
如果在 template 里使用的是 reactive 类型的数据,那么 Vue 不会自动帮我们添加 .value
Vue 是如何决定是否需要添加 .value 的?
Vue 在解析数据之前,会自动判断这个数据是否是 ref 类型的,如果是就自动添加 .value,如果不是就不自动添加 .value
Vue 是如何判断当前数据是否是 ref 类型的?
通过当前数据的 __v_isRef 来判断的
如果存在这个私有的属性,并且取值为 true,那么就代表是一个 ref 类型的数据
因为是私有属性,所以我们是访问不到 __v_isRef 属性的值
Vue 提供了 isRef 和 isReactive 方法来判断一个数据是 ref 类型还是 reactive 类型