vue2源码-二、对象响应式原理
对象响应式原理
初始化操作,扩展
init
方法:
// index.js function Vue(options) { this._init(options) } initMixin(Vue) // 扩展了init方法 export default Vue
在
initMinin
方法中,扩展了init
方法。以下获用户的
option
。
// init.js import { initState } from './state.js' // 就是给Vue增加init方法的 export function initMixin(Vue) { // 初始化操作 Vue.prototype._init = function (options) { // vue vm.$options就是获取用户的配置 // 使用vue的时候$是vue定义的,而且再实例上 const vm = this vm.$options = options // 将用户的选项挂载到实例上 // 初始化状态 initState(vm) } }
核心模块
observe
:数据监测data数据的响应式原理:通过
Object.definProperty
重写data
上的所有属性。调用的
initState
方法,这个方法需要对数据进行劫持。
import { observe } from './observe/index' // 主函数 // 1. 封装主函数,如果存在data属性,则进行初始化数据 export function initState(vm) { const opts = vm.$options // options不是空 if (opts.data) { initData(vm) } } // vm._data.name 变成vm.name 代理 function proxy(vm, target, key) { Object.defineProperty(vm, key, { get() { return vm[target][key] }, set(newValue) { vm[target][key] = newValue }, }) } // 2.初始化数据 function initData(vm) { let data = vm.$options.data // 可能是函数和对象 // data可能是函数也可能是对象,函数需要进行this绑定。 data = typeof data === 'function' ? data.call(vm) : data // data是用户返回的对象 vm._data = data // 将返回的对象放到_data // 对数组进行劫持vue2里采用一个api defineProperty // 3.后面会提及 observe(data) // 将vm._data用vm来代理就可以了 for (let key in data) { proxy(vm, '_data', key) } }
Obsever类:对对象进行观测。
observe
方法:
export function observe(data) { // 对这个对象进行劫持 if (typeof data !== "object" || data === null) { return; // 只对对象进行劫持 } // 如果一个对象被劫持过了,那就不需要在劫持了(判断一个对象是否被劫持过,可以添加一个实例,用实例来判断是否被劫持过) return new Observe(data); }
这个方法返回了一个输入数据的观测对象。
那返回一个什么样的对象呢?
// 循环对象进行一次劫持 class Observer{ constructor(value){ this.walk() } walk(data) { // 重新定义属性 Object.keys(data).forEach((key) => defineReactive(data, key, data[key])) } } // 属性劫持 // 对对象target,定义属性key,值为value // 使用Object.definProperty重新定义data的属性 export function defineReactive(target, key, value) { observe(value) // 递归对所有的属性进行劫持 Object.defineProperty(target, key, { // 用户取值 get() { console.log('用户设置值00') return value }, // 用户设置值了 set(newValue) { console.log('用户取值了') if (newValue === value) return // 递归,设置了对象 observe(newValue) value = newValue }, }) }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!