vue2中响应式系统原理
创始人
2025-05-29 15:55:54

框架

  • 每个组件实例都会对应一个watcher实例,在组件渲染过程中把接触过的数据property记录为依赖。当依赖项的setter触发时,会通知watcher,重新渲染组件

  • vue实例中的data选项,在初始化时会遍历该对象所有属性,并使用Object.defineProperty转为getter/setter。

组件结构

Observer:主要是将对象转为响应式对象,在getter中,会创建Dep来收集依赖

Dep:用于存放watcher,即副作用函数effectFn

Watcher:观察者,当有数据更新时,会触发update

源码解析

在哪里绑定vue实例与watcher实例

在src/core/instance/lifecycle.ts中的mountComponent中

export function mountComponent(vm: Component,el: Element | null | undefined,hydrating?: boolean
): Component {vm.$el = elcallHook(vm, 'beforeMount')let updateComponent/* istanbul ignore if */updateComponent = () => {vm._update(vm._render(), hydrating)}const watcherOptions: WatcherOptions = {before() {if (vm._isMounted && !vm._isDestroyed) {callHook(vm, 'beforeUpdate')}}}// we set this to vm._watcher inside the watcher's constructor// since the watcher's initial patch may call $forceUpdate (e.g. inside child// component's mounted hook), which relies on vm._watcher being already definednew Watcher(vm,updateComponent,noop,watcherOptions,true /* isRenderWatcher */)hydrating = false// flush buffer for flush: "pre" watchers queued in setup()const preWatchers = vm._preWatchersif (preWatchers) {for (let i = 0; i < preWatchers.length; i++) {preWatchers[i].run()}}// manually mounted instance, call mounted on self// mounted is called for render-created child components in its inserted hookif (vm.$vnode == null) {vm._isMounted = truecallHook(vm, 'mounted')}return vm
}

vue实例中的data响应式初始化

在src/core/instance/state.ts/initData中,主要是observe(data)这个

function initData(vm: Component) {let data: any = vm.$options.datadata = vm._data = isFunction(data) ? getData(data, vm) : data || {}if (!isPlainObject(data)) {data = {}}// proxy data on instanceconst keys = Object.keys(data)const props = vm.$options.propsconst methods = vm.$options.methodslet i = keys.lengthwhile (i--) {const key = keys[i]if (props && hasOwn(props, key)) {} else if (!isReserved(key)) {proxy(vm, `_data`, key)}}// observe dataconst ob = observe(data)ob && ob.vmCount++
}

对Object的变化监测

Observer只追踪数据是否被修改,无法追踪新增和删除属性

Vue提供了Vue.prototype.$set和Vue.prototype.$delete,内部也是调用Observer的方法

import {set,del
} from '../observer/index'Vue.prototype.$set = set
Vue.prototype.$delete = del

相关内容

热门资讯

扎心,为什么越忙越穷? 扎心代... 点击 “简七读财” ,发送消息“ 理财 ”小白轻松入门~晚上好,我是简七编辑部的艾小白。前阵子和一...
11月21日这些公告有看头 1... 2025.11.21以下是第一财经对一些重要公告的汇总,供投资者参考。【品大事】中央商场:公司及祝珺...
首都资本市场“十四五”交出亮眼... 11月21日,市政府新闻办举办首都“十四五”规划高质量收官系列主题新闻发布会金融业发展成就专场。北京...
聚石化学、豪尔赛被证监会立案;... 今日焦点兆易创新:部分董事、高级管理人员拟合计减持24.9万公司股份兆易创新公告称,副董事长、总经理...
V观财报|宁水集团股东王开拓被...   中新经纬11月21日电 宁波证监局网站21日发布《关于对王开拓采取责令购回违规减持股份并向上市公...