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

相关内容

热门资讯

大资金连砸几千亿,A股本周为何... 刚过去的交易周(1月19日至23日),是 A股市场 在监管“降温”信号出现后,经历的首个完整交易周。...
黄仁勋偷偷高调背后,是2026... “我和黄仁勋的共同点找到了——都爱吃耙耙柑啊!”1月24日下午,黄仁勋突然一个闪现,出现在上海浦东陆...
0元购成常态,酒店交易市场更热... 文|迈点酒店资产交易市场的热闹劲儿,从2025年末一直燃到了2026年初。刚踏入新一年,杭州武林广场...
26年仅1家目标销量翻倍,车企... 这些年,各家车企可以说是各种高歌猛进,销量放卫星的现象并不罕见,但是2026年伊始,我们看到各家车企...
精度季报丨陈皓:看好AI和化工... (本文仅仅是个人角度的臆想分析,不能作为投资建议。)牛市来了,人人都会炒股了...就比如基毛哥,之前...