71 Vue3.0 是如何变得更快的
diff 方法优化
-
Vue2.x
中的虚拟 dom 是进行全量的对比。 -
Vue3.0
中新增了静态标记(PatchFlag):在与上次虚拟结点进行对比的时候,值对比 带有 patch flag 的节点,并且可以通过 flag 的信息得知当前节点要对比的具体内容化
hoistStatic 静态提升
-
Vue2.x
: 无论元素是否参与更新,每次都会重新创建。 -
Vue3.0
: 对不参与更新的元素,只会被创建一次,之后会在每次渲染时候被不停的复用
cacheHandlers 事件侦听器缓存
默认情况下 onClick 会被视为动态绑定,所以每次都会去追踪它的变化但是因为是同一 个函数,所以没有追踪变化,直接缓存起来复用即可
72 说说你对 proxy 的理解
vue 的数据劫持有两个缺点
-
无法监听通过索引修改数组的值的变化 -
无法监听 object 也就是对象的值的变化 -
所以 vue2.x 中才会有 $set
属性的存在 -
proxy 是 es6 中推出的新 api,可以弥补以上两个缺点,所以 vue3.x 版本用 proxy 替换 object.defineproperty
。
73 生命周期详解
*init*
-
initLifecycle/Event
,往vm上挂载各种属性 -
callHook: beforeCreated
: 实例刚创建 -
initInjection/initState
: 初始化注入和data
响应性 -
created: 创建完成,属性已经绑定, 但还未生成真实
dom` -
进行元素的挂载:
$el / vm.$mount()
-
是否有
template
: 解析成
render function
-
*.vue
文件:vue-loader
会将<template>
编译成render function
-
beforeMount
: 模板编译/挂载之前 -
执行
render function
,生成真实的dom
,并替换到dom tree
中 -
mounted
: 组件已挂载
update
-
执行
diff
算法,比对改变是否需要触发UI
更新 -
flushScheduleQueue
-
watcher.before
: 触发beforeUpdate
钩子 –watcher.run()
: 执行watcher
中的notify
,通知所有依赖项更新UI -
触发
updated
钩子: 组件已更新 -
actived / deactivated(keep-alive)
: 不销毁,缓存,组件激活与失活 -
destroy
-
remove()
: 删除节点 -
watcher.teardown()
: 清空依赖 -
vm.$off()
: 解绑监听 -
beforeDestroy
: 销毁开始 -
销毁自身且递归销毁子组件以及事件监听 -
destroyed
: 完成后触发钩子
上面是vue的声明周期的简单梳理,接下来我们直接以代码的形式来完成vue的初始化
new Vue({})
// 初始化Vue实例
function _init() {
// 挂载属性
initLifeCycle(vm)
// 初始化事件系统,钩子函数等
initEvent(vm)
// 编译slot、vnode
initRender(vm)
// 触发钩子
callHook(vm, 'beforeCreate')
// 添加inject功能
initInjection(vm)
// 完成数据响应性 props/data/watch/computed/methods
initState(vm)
// 添加 provide 功能
initProvide(vm)
// 触发钩子
callHook(vm, 'created')
// 挂载节点
if (vm.$options.el) {
vm.$mount(vm.$options.el)
}
}
// 挂载节点实现
function mountComponent(vm) {
// 获取 render function
if (!this.options.render) {
// template to render
// Vue.compile = compileToFunctions
let { render } = compileToFunctions()
this.options.render = render
}
// 触发钩子
callHook('beforeMounte')
// 初始化观察者
// render 渲染 vdom,
vdom = vm.render()
// update: 根据 diff 出的 patchs 挂载成真实的 dom
vm._update(vdom)
// 触发钩子
callHook(vm, 'mounted')
}
// 更新节点实现
funtion queueWatcher(watcher) {
nextTick(flushScheduleQueue)
}
// 清空队列
function flushScheduleQueue() {
// 遍历队列中所有修改
for(){
// beforeUpdate
watcher.before()
// 依赖局部更新节点
watcher.update()
callHook('updated')
}
}
// 销毁实例实现
Vue.prototype.$destory = function() {
// 触发钩子
callHook(vm, 'beforeDestory')
// 自身及子节点
remove()
// 删除依赖
watcher.teardown()
// 删除监听
vm.$off()
// 触发钩子
callHook(vm, 'destoryed')
}
74 Proxy 相比于 defineProperty 的优势
-
数组变化也能监听到 -
不需要深度遍历监听
let data = { a: 1 }
let reactiveData = new Proxy(data, {
get: function(target, name){
// ...
},
// ...
})
75 vue-router
mode
-
hash
-
history
跳转
-
this.$router.push()
-
<router-link to=""></router-link>
占位
<router-view></router-view>
76 vuex总结
-
state
: 状态中心 -
mutations
: 更改状态 -
actions
: 异步更改状态 -
getters
: 获取状态 -
modules
: 将state
分成多个modules
,便于管理
77 diff 算法
时间复杂度: 个树的完全diff
算法是一个时间复杂度为O(n*3)
,vue进行优化转化成O(n)
。
理解:
-
最小量更新,
key
很重要。这个可以是这个节点的唯一标识,告诉
diff
算法,在更改前后它们是同一个DOM节点
-
扩展 v-for
为什么要有key
,没有key
会暴力复用,举例子的话随便说一个比如移动节点或者增加节点(修改DOM),加key
只会移动减少操作DOM。 -
只有是同一个虚拟节点才会进行精细化比较,否则就是暴力删除旧的,插入新的。
-
只进行同层比较,不会进行跨层比较。
diff算法的优化策略:四种命中查找,四个指针
-
旧前与新前(先比开头,后插入和删除节点的这种情况) -
旧后与新后(比结尾,前插入或删除的情况) -
旧前与新后(头与尾比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧后之后) -
旧后与新前(尾与头比,此种发生了,涉及移动节点,那么新前指向的节点,移动到旧前之前)
78 Vue 的响应式原理中 Object.defineProperty 有什么缺陷
-
Object.defineProperty
无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应; -
Object.defineProperty
只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy 可以劫持整个对象,并返回一个新的对象 -
Proxy
不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性
79 Composition API
-
Composition API
出现就是为了解决Options API导致相同功能代码分散的现象

compositon api提供了以下几个函数:
-
setup
-
ref
-
reactive
-
watchEffect
-
watch
-
computed
-
toRefs
-
生命周期的 hooks
80 vue中是如何检测数组变化的呢
数组就是使用
object.defineProperty
重新定义数组的每一项,那能引起数组变化的方法我们都是知道的,pop
、push
、shift
、unshift
、splice
、sort
、reverse
这七种,只要这些方法执行改了数组内容,我就更新内容就好了,是不是很好理解
-
是用函数劫持的方式,重写了数组方法,具体呢就是更改了数组的原型,更改成自己的,用户调数组的一些方法的时候,走的就是自己的方法,然后通知视图去更新 -
数组里每一项可能是对象,那么我就是会对数组的每一项进行观测,(且只有数组里的对象才能进行观测,观测过的也不会进行观测)
vue3
:改用proxy
,可直接监听对象数组的变化
原文始发于微信公众号(消失的程序员):Vue.js面试题精选—8
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/250893.html