面试取经: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)
}
相关推荐
vortex52 分钟前
深度字典攻击(实操笔记·红笔思考)
前端·chrome·笔记
我是伪码农4 分钟前
Vue 1.30
前端·javascript·vue.js
利刃大大12 分钟前
【Vue】默认插槽 && 具名插槽 && 作用域插槽
前端·javascript·vue.js
试着14 分钟前
【huawei】机试
华为·面试·机试·手搓代码
艳阳天_.15 分钟前
web 分录科目实现辅助账
开发语言·前端·javascript
风之舞_yjf23 分钟前
Vue基础(27)_脚手架安装
vue.js
编程彩机24 分钟前
互联网大厂Java面试:从分布式事务到微服务优化的技术场景解读
java·spring boot·redis·微服务·面试·kafka·分布式事务
编程彩机28 分钟前
互联网大厂Java面试:从Spring WebFlux到分布式事务的技术场景解析
java·微服务·面试·分布式事务·spring webflux
小白640233 分钟前
2025年终总结-迷途漫漫,终有一归
前端·程序人生
烟花落o37 分钟前
贪吃蛇及相关知识点讲解
c语言·前端·游戏开发·贪吃蛇·编程学习