面试取经: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)
}
相关推荐
程序员二叉11 小时前
【Java】集合面试全套精讲|HashMap/ArrayList高频考点完整版
java·面试·哈希算法
原则猫13 小时前
HOOKS 背后机制
前端
码语智行13 小时前
首页导航跳转功能深度解析-系统内和系统外
前端
不懂数据的小白13 小时前
面试题一:【三】AB实验入门(验证)
面试
阿猫的故乡14 小时前
Vue过渡动画从入门到装X:淡入淡出、滑动、列表动画、第三方库全搞定
前端·javascript·vue.js
我叫黑大帅14 小时前
通过php 中的Route:: 的写法了解什么是静态类调用
后端·面试·php
裕波14 小时前
Vue&ViteConf 2026 将于 7 月 18 日在上海举办,尤雨溪将现场发表主题演讲
vue.js·vite
IManiy14 小时前
总结之Vibe Coding前端骨架
前端
JS菌14 小时前
AI Agent 沙箱双层防护体系:从权限过滤到内核隔离的完整实现
前端·人工智能·后端
Aphasia31114 小时前
从输入URL到页面展示全流程
前端·面试