1.vue响应式原理是什么?vue3的响应式有何不同
Vue在初始化数据时,会使用Object.defineProperty
重新定义data中的所有属性,当页面使用对应属性时,首先会进行依赖收集(收集当前组件的watcher
)如果属性发生变化会通知相关依赖进行更新操作(发布订阅
)。
Vue3.x改用Proxy
替代Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。
❝
Proxy只会代理对象的第一层,那么Vue3又是怎样处理这个问题的呢?
❞
(很简单啊)
判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive
方法做代理, 这样就实现了深度观测。
❝
监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?
❞
我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。
2.vue组件通信方式有哪些及原理
父子组件通信
父->子props
,子->父 $on、$emit
获取父子组件实例 $parent、$children
Ref
获取实例的方式调用组件的属性或者方法
Provide、inject
官方不推荐使用,但是写组件库时很常用
兄弟组件通信
javascript
代码解读
复制代码
Event Bus` 实现跨组件通信 `Vue.prototype.$bus = new Vue
Vuex
跨级组件通信
bash
代码解读
复制代码
Vuex
$attrs、$listeners
3. keep-alive的常用属性有哪些及实现原理
keep-alive
可以实现组件缓存,当组件切换时不会对当前组件进行卸载。
常用的两个属性include/exclude
,允许组件有条件的进行缓存。
两个生命周期activated/deactivated
,用来得知当前组件是否处于活跃状态。
keep-alive的中还运用了LRU(Least Recently Used)
算法。
4.如何实现 vue 项目中的性能优化?
编码阶段
- 尽量减少 data 中的数据,data 中的数据都会增加 getter 和 setter,会收集对应的 watcher
- v-if 和 v-for 不能连用
- 如果需要使用 v-for 给每项元素绑定事件时使用事件代理
- SPA 页面采用 keep-alive 缓存组件
- 在更多的情况下,使用 v-if 替代 v-show
- key 保证唯一
- 使用路由懒加载、异步组件
- 防抖、节流
- 第三方模块按需导入
- 长列表滚动到可视区域动态加载
- 图片懒加载
SEO 优化
- 预渲染
- 服务端渲染 SSR
打包优化
- 压缩代码
- Tree Shaking/Scope Hoisting
- 使用 cdn 加载第三方模块
- 多线程打包 happypack
- splitChunks 抽离公共文件
- sourceMap 优化
用户体验
- 骨架屏
- PWA
还可以使用缓存(客户端缓存、服务端缓存)优化、服务端开启 gzip 压缩