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

相关内容

热门资讯

科技通报“嘻游联盟 透视”!... 您好:嘻游联盟这款游戏可以开挂,确实是有挂的,需要软件加微信【3398215】很多玩家在这款游戏中打...
重大通报“斗娱游戏究竟是不是真... 亲.斗娱游戏这款游戏是可以开挂的,确实是有挂的,通过添加客服【4830828】很多玩家在这款游戏中怀...
实测建议-" 双盈休... 您好:双盈休闲这款游戏可以开挂,确实是有挂的,需要软件加微信【9503776】,很多玩家在双盈休闲这...
「实测讲解」皇豪众娱.到底有挂... 「实测讲解」皇豪众娱.到底有挂吗[太坑了原来有挂]亲.皇豪众娱这款游戏是可以开挂的,确实是有挂的,通...
独家揭秘「新圣游炸金花」怎么开... 独家揭秘「新圣游炸金花」怎么开挂!太坑了,果然有挂您好:新圣游炸金花这款游戏可以开挂,确实是有挂的,...