面试取经: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)
}
相关推荐
彭亚川Allen16 分钟前
从零手搓 RAG 之检索全流程,给大模型接上自己的知识库
前端·后端·ai编程
IT_陈寒18 分钟前
别让Java字符串拼接偷偷吃掉你的内存
前端·人工智能·后端
软件技术NINI1 小时前
圣罗兰彩妆html+css 4页
前端·css·html
2601_951615201 小时前
网站模板 网站网页模板下载
前端·网络·html
酷炫码神2 小时前
Day 1|HTML5:一个商城首页的骨架,从 DOCTYPE 到语义化
前端·html·html5
AI源码2 小时前
鲜花商城(HTML 版)
前端·html
hiahiahia1232 小时前
Message 和对话
服务器·前端·数据库
雪芽蓝域zzs3 小时前
第 7 节:多边形点击弹窗 + 清空绘制按钮
vue.js
溪语流沙3 小时前
【Web全栈进阶】Composition API与组件通信:props深入、emit、插槽
前端·css·vue.js
ZoeLandia3 小时前
TypeScript 03:泛型与工具类型
前端·typescript