vue总结
Vue 总结
对 proxy
& Object.defineProperty
理解
Object.defineProperty
的主要三个问题:
- 不能监听数组变化 :无法监听到数组下标的变化,导致通过数组下标添加元素,不能实时响应
- 必须遍历对象的每个属性 :只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果属性值是对象,还需要深度遍历。
- 必须深层遍历嵌套对象
Proxy
的优势:
- 针对对象:针对整个对象,而不是对象的某个属性
- 支持数组:
Proxy
不需要对数组的方法进行重载,省去了众多hack Proxy
的第二个参数可以有13种拦截方法:不限于apply
、ownKeys
、deleteProperty
、has
等等是Object.defineProperty
不具备的Proxy
返回的是一个新对象,我们可以只操作新的对象达到目的,而Object.defineProperty
只能遍历对象属性直接修改Proxy
作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利
Object.defineProperty
的优势:
兼容性好,支持
IE9
,而Proxy
的存在浏览器兼容性问题,而且无法用polyfill
磨平
defineProperty
的属性值
Object.defineProperty(obj, prop, descriptor)
// obj 要定义属性的对象
// prop 要定义或修改的属性的名称
// descriptor 要定义或修改的属性描述符
Object.defineProperty(obj,"name",{
value:"poetry", // 初始值
writable:true, // 该属性是否可写入
enumerable:true, // 该属性是否可被遍历得到(for...in, Object.keys等)
configurable:true, // 定该属性是否可被删除,且除writable外的其他描述符是否可被修改
get: function() {},
set: function(newVal) {}
})
Proxy
只会代理对象的第一层,那么Vue3
又是怎样处理这个问题的呢?
判断当前
Reflect.get的
返回值是否为Object
,如果是则再通过reactive
方法做代理, 这样就实现了深度观测。
监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?
我们可以判断
key
是否为当前被代理对象target
自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger
Vue中依赖收集
- 每个属性都有自己的
dep
属性,存放他所依赖的watcher
,当属性变化之后会通知自己对应的watcher
去更新 - 默认会在初始化时调用
render
函数,此时会触发属性依赖收集dep.depend
- 当属性发生修改时会触发
watcher
更新dep.notify()
Vue实例挂载的过程中发生了什么
- 挂载过程指的是
app.mount()
过程,这个过程中整体上做了两件事:初始化和建立更新机制 - 初始化会创建组件实例、初始化组件状态,创建各种响应式数据
- 建立跟新机制这一步会立即执行一次更新函数,这会首次执行组件渲染函数并执行
patch
将前面获得vnode
转换为dom
;同时首次执行函数会创建它内部响应式数据之间和组件更新函数之间的依赖关系,这使得以后数据变化时会执行对应的更新函数
Vue
初始化主要就干了几件事情,合并配置
,初始化生命周期
,初始化事件中心
,初始化渲染
,初始化 data
、props
、computed
、watcher
等
watch
和watchEffect
区别
watch
需要明确监听哪个属性watchEffect
会根据其中属性,自动监听其变化, 初始化时,一定会执行一次(收集要监听的数据)
setup
中如何获取组件实例
通过getCurrentInstance
获取当前实例
Vue3为何比Vue2快
Proxy
响应式:深度监听,性能更好(获取到哪一层才触发响应式get
,不是一次性递归)PatchFlag
动态节点做标志HoisStatic
将静态节点的定义,提升到父作用域,缓存起来。多个相邻的静态节点,会被合并起来CacheHandler
事件缓存SSR
优化:静态节点不走vdom
逻辑,直接输出字符串,动态节点才走Tree-shaking
根据模板的内容动态import
不同的内容,不需要就不import
什么是Patchflag
- 模板编译时,动态节点做标记
- 标记,分为不同类型,如
Text
、PROPS
、CLASS
diff
算法时,可区分静态节点,以及不同类型的动态节点
什么是Hoist和CacheHandler
Hoist
- 将静态节点的定义,提升到父作用域,缓存起来
- 多个相邻静态节点,会被合并起来
- 典型的拿空间换时间的优化策略
CacheHandler 缓存事件
Vite 为什么启动非常快
- 开发环境使用
Es6 Module
,无需打包,运行时编译,非常快 - 生产环境使用
rollup
,并不会快很多
Composition API 和 React Hooks 的对比
- 前者
setup
(相当于created
、beforeCreate
的合集)只会调用一次,而React Hooks
函数在渲染过程中会被多次调用 Composition API
无需使用useMemo
、useCallback
,因为setup
只会调用一次,在setup
闭包中缓存了变量Composition API
无需顾虑调用顺序,而React Hooks
需要保证hooks
的顺序一致(比如不能放在循环、判断里面)Composition API
的ref
、reactive
比useState
难理解
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Jonathan
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果