面试取经:Vue篇-Vue2响应式原理

Vue2响应式原理

  1. 劫持数据属性,完成数据响应式
  2. 获取数据时,完成依赖收集工作
  3. 修改数据时,完成派发更新操作

数据劫持-Observer

vue 会遍历data中的属性,通过Object.defineProperty()给每个属性添加get和set方法

javascript 复制代码
data(){
    return {
        name:'john',
        info:{
            school:'xxx'
        }
    }
}
​
​
​
Object.defineProperty('name',{
    get(){
       // 获取时运行 
    }
    set(value){
        // 修改时运行
    }
})
​
// 针对info会深度遍历

后续,动态的添加和删除属性是无法检测的

arduino 复制代码
info.age = '18' // 检测不到
delete info.school // 检测不到

但vue提供了set和delete实现上述的检测

kotlin 复制代码
this.$set(this.info,age,'18')
this.$delete(this.info,school)

针对数组,vue修改了它的隐式原型

ini 复制代码
[1,2,3]._proto_ = defVue // Vue 自定义对象
defVue._proto_ = Array.prototype

数组存在缺陷

  • 检测不到 数组长度的变化
  • 检测不到根据索引修改元素

依赖收集-Dep

在数据劫持的过程中,vue会为响应式对象中的每个属性,对象本身,数组本身创建一个Dep实例,Dep实例可以完成记录依赖以及派发更新的工作,当读取响应式对象的某个属性时,进行依赖的收集depend()

具体依赖收集过程-Watcher

Vue在初始化时,会为每一个组件实例创建一个watcher,watcher中记录了该组件的render函数,首次挂载时,即在mounted阶段,watcher会先运行一次render函数,完成依赖的收集(将用到的响应式数据与watcher进行关联)

scss 复制代码
new Watcher(render)
​
render(){
    // this.a
    // 调用get
    // get调用时,dep.depend() 记录wather
}

派发更新-Update

当改变某个属性时,进行派发更新notify()

kotlin 复制代码
// 数据修改
this.a = '1'
// 调用set
// set调用时,dep.notify() 通知watcher运行render函数,界面重新渲染并重新记录当前依赖

更新过程-Scheduler

watcher 收到派发更新通知后,并非立即执行对应的函数,而是把自己交给一个叫做调度器的东西,由其完成,调度器维护一个执行队列,该队列同一个watcher仅会存在一次,队列中的watcher会被调度器通过nextTick函数放到事件循环的微任务队列

scss 复制代码
nextTick(){
    Promise.resolve().then(watcher)
}
相关推荐
软件派15 小时前
生产动态数据智能风控:阈值判别、趋势预测、异常识别算法工程落地实战
前端·数据库·算法
考研保研资料分享18 小时前
2022双非保研华科热能工程:三校考核、传热题与报名复盘
面试
花开盛夏^.^1 天前
电脑打开多个浏览器Web窗口占用较大的运行内存的原因
前端·浏览器
weixin_307779131 天前
RAG 面试陷阱——混合检索并非无条件优越:一个条件反转实验
人工智能·python·面试·职场和发展
馒头不想说话1 天前
实体店老板的24小时AI运营员工,写、剪、发全自动,省下一整个团队工资
前端
nice_lcj5201 天前
深入理解 Java 反射:从 Class 对象到方法调用(含性能实测 + 迷你 IOC 实战 + 面试考点)
java·开发语言·后端·面试
椒哥1 天前
一天被问几十次"允许",我统计了 517 次,然后写了个插件
前端·javascript·github
风骏时光牛马1 天前
生成一个AI稳定性治理及疑难问题分析标题,只需要一个标题,不需要其他的任何文本。
前端
莫西干式秃头1 天前
用 AI + threejs 写了个浏览器里的 3D 动作游戏《武来》:砍怪、放技能、开 SU7
前端·人工智能·three.js
kyriewen1 天前
我测了 6 种防请求竞态的写法:只有 1 种真能打
前端·javascript·程序员