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