如何理解 Composition API 和 Options API
Composition API 带来了什么?
● 更好的代码组织(options:逻辑散落在各地,composition,把相关的逻辑集中到一块儿去,可以提高代码组织能力)
● 更好的逻辑复用
● 更好的类型推导
(主要为一些大型的,复杂的项目而设计)
Composition API 和 Options API 如何选择?
● 不建议共用,会引起混乱
● 小型项目、业务逻辑简单,用 Options API
● 中大型项目、逻辑复杂,用 Composition API
总的来说,还是要看场景;
如何理解 ref toRef 和 toRefs
ref
- 生成值类型的响应式数据
- 可用于模板和 reactive
- 通过 .value 修改值
-
此外,ref 还能获取 dom 元素:
要点
ref:用 .value 修改值 (如果用模板和 reactive,就不需要用 .value)
代码规范:ref 变量,后面加个 Ref 后缀。如 ageRef 。清晰,可读性好,利于维护。
toRef
- 针对一个响应式对象( reactive 封装的)的 prop(属性),创建一个 ref,具有响应式;
- 两者保持引用关系(一方改了,另一方也跟着改)
普通对象要实现响应式,用 reactive;reactive 的某个属性需要单独拎出来实现响应式,就用 toRef。
toRefs
- 将响应式对象(reactive 封装)转换成普通对象
- 对象的每个 prop 都是对应的 ref
- 两者保持引用关系
** ref toRef toRefs 最佳使用方式:
- 用 reactive 做对象的响应式,用 ref 做值类型的响应式
- setup 中返回 toRefs(state),或者 toRef(state, ‘xxx’) (在模板中使用会方便点)
- ref 的变量命名都用 xxxRef (代码规范,养成良好的代码习惯)
- 合成函数返回响应式对象时,使用 toRefs
为什么需要用 ref
为何需要 ref ?
- 返回值类型,会丢失响应式;
- 如在 setup、computed、合成函数,都有可能返回值类型;
- Vue 如不定义 ref,用户将自造 ref, 反而混乱;
vue3 的响应式是通过 proxy 来实现的。proxy 对对象才有用,对值类型无能为力。
为何需要 .vaule
1.实现响应式
2.保持响应式
- ref 是一个对象(不丢失响应式,),value 存储值;
- 通过 .value 属性的 get 和 set 实现响应式;
- 用于模板、reactive 时,不需要 .value,其他情况都需要;
因为值类型不具备响应式;(值类型不是引用传递)
为何需要toRef 和 toRefs
- 初衷:不丢失响应式的情况下,把对象数据分解/扩散(解构);
- 前提:针对的是响应式对象(reactive 封装的),非普通对象;
- 注意:toRef 和 toRefs 不创造响应式,而是延续响应式;
vue3 升级了哪些重要的功能?
升级的功能
1.createApp:
2.emits 属性:
3.生命周期
4.多事件:
5.fragment (vue3 不需要父节点包裹,如下图这样写不会报错):
6.移除 .sync
7.异步组件的写法 (vue3 的异步组件需要引入一个 defineAsyncComponent 的方法)
8.移除 filter
9.teleport
10.suspense
11.composition API
* composition API
- reactive: 创建响应式数据
- ref 相关
- readonly: 创建只读的数据
- watch 和 watchEffect 监听数据
- setup (相当于beforecreate 和 created 两个生命周期)
- 生命周期钩子函数
Vue3 如何实现响应式
Object.defineProperty 的缺点
- 深度监听需要一次性递归
- 无法监听新增属性/删除属性( Vue.set Vue.delete )
- 无法原生监听数组,需要特殊处理
Proxy
Proxy 参考资料
Proxy MDN
ECMAScript 6入门
Reflect
new Proxy(target, handler);
- target 目标对象(可以是任何类型的对象,包括原生数组,函数,甚至另一个代理)
- handler 一个对象,其属性是操作对应的自定义代理函数
Reflect 的作用:
- 和 proxy 能力一一对应。
- 规范化、标准化、函数式
- 替代掉 Object 上的工具函数。
Reflect.has(obj, 'prop')
Reflect.deletePorperty(obj, 'prop')
Reflect.ownKeys
** 性能如何优化的?
- vue2 用 object.defineProperty 时: 一开始就递归到底。
- proxy:proxy 的深度监听是在 get 的时候递归的,也就是说,什么时候用什么时候递归。
- 比如只是获取 data.info:不会往下递归。(获取到哪一层,哪一层才会触发响应式)
Proxy 实现响应式
- 深度监听,性能更好
- 可监听 新增/删除 属性
- 可监听数组变化
总结
- Proxy 能规避 Object.defineProperty 的问题
- Proxy 无法兼容所有浏览器,无法 polyfill
*watch 和 watchEffect 的区别
很细节的问题。
- 两者都可以监听 data 属性变化;
- watch 需要明确监听哪个属性;
- watchEffect 会根据其中的属性,自动监听其变化。
watch:
如果要立马执行:
watch(numberRef, (newNumber, oldNumber) => {
console.log('ref watch', newNumber, oldNumber)
}, {
immediate: true // 初始化之前就监听,可选
})
watchEffect
初始化时,一定会执行一次。为什么?—— 需要收集要监听的数据。
* setup 中如何获取组件实例
一般情况下也不需要获取组件实例。
- 在 setup 和其他 Composition API 中没有 this;
- 可通过 getCurrentInstance 获取当前实例;
- 若使用 Options API 可照常使用 this;
const instance = getCurrentInstance()
console.log('instance', instance)
console.log('x', instance.data.x) // x undefined
* Vue3 为何比 Vue2 快
- Proxy 响应式
- PatchFlag
- hoistStatic
- cacheHandler
- SSR 优化
- tree-shaking
* PatchFlag (静态标记)
- 编译模板时,动态节点做标记
- 标记,分为不同的类型,如 TEXT、PROPS 等
- diff 算法时,可以区分静态节点,以及不同类型的动态节点(优化 diff 算法)
动态节点:加了插值,或者动态的属性之类。
可以用这个工具来观察一下:Vue3 Template Explorer
hoistStatic
- 将静态节点的定义,提升到父作用域,缓存起来;(空间换时间,内存会多点)
- 多个相邻的静态节点,会被合并起来(编译优化);
- 典型的拿空间换时间的优化策略;
cacheHandler 缓存事件
- 缓存事件
有缓存就去拿缓存,没有缓存就定义一个函数(拿空间换时间)
SSR 优化
- 静态节点直接输出,绕过了 vdom;
- 动态节点,还是需要动态渲染;
tree shaking
- 编译时,根据不同的情况,引入不同的 API
-
根据模板里用到的,需要什么就 import 什么。
Vite 为什么启动非常快
Vite 是什么
- 一个前端打包工具,Vue 作者发起的项目
- 借助 Vue 的影响力,发展较快, 和 webpack 竞争
- 优势:开发环境下无需打包,启动快
Vite 为何启动快?
- 开发环境使用 ES6 Module, 无需打包——非常快。
- 生产环境使用 rollup,并不会快很多。
开发环境:前提,线上环境暂时还不能用,因为线上环境 ES6 Module 没那么普及
无需打包:无需像 webpack 一样去打包成 ES5 这种形式。
webpack:需要打包成 es5,浏览器再去运行。
vite: 类似于用 html 直接引入 es6 模块化的方式,来直接执行,不用打包,所以快。
* Composition API 和 React Hooks 的对比
- 前者 setup (作为生命周期)只会被调用一次,而后者函数(函数组件)会被多次调用(最根本的区别,设计理念的不同)
- 前者无需 useMemo、useCallback(缓存数据、缓存函数),因为 setup 只调用一次;
- 前者无需顾虑调用顺序,而后者需要保证 hooks 的顺序一致(hooks 不能放在判断和循环中)。
- 前者 react + ref 比后者 useState 要难理解。
Vue3 相关题目
- Vue3 与 Vue2 相比,有什么优势?
- 描述 Vue3 生命周期(Composition API 的生命周期 、Options API 的生命周期)
- 如何看待 Composition API 和 Options API ?(注意 Composition API 是高级功能,不是基础必会,并不是有了它就要弃用 Options API)
- 如何理解 ref toRef 和 toRefs ?
- Vue3 升级了哪些重要的功能?
- Vue3 如何实现代码逻辑复用?(Composition API )
- Vue3 如何实现响应式(考察 proxy 的语法和 proxy 的使用)
- watch 和 watchEffect 的区别是什么?
- setup 中如何获取组件实例?(其实考察的要点是:vue3 的 Composition API 其实没有 this)
- Vue3 为何比 Vue2 快?(编译优化相关的几个要点)
- Vite 是什么?(以及 vite 为什么快?es module…… )
- Compositon API 和 React Hooks 的对比
后记
学习笔记,知识点的整理归纳。