Vue 2.0
- new Vue({})
- initMixin(Vue) 将_init方法是挂载在Vue原型的方法
- _init 赋值传入的 options(1 步骤传入的)参数, 执行initState 方法
- initState,依次初始化 prop>methods>data>computed>watch
- initData
-
把data数据代理到vm 也就是Vue实例上面 我们可以使用this.a来访问this._data.a
-
对数据进行观测 --响应式数据核心
-
递归嵌套 监测每一项data数据,除非数组和Object 对象,创建Observer对象 new Observer(value)
-
Observer对象 构造函数中,增加了一个不可枚举的__ob__属性,防止已经被响应式观察的数据反复被观测 其次 响应式数据可以使用__ob__来获取 Observer 实例的相关方法 这对数组很关键。
针对Object 对象 直接使用Object.defineProperty() 进行数据劫持,set 方法 会通知watcher 依赖视图更新。视图数据绑定,调用get方法, get 方法 会生成dep对象 -> watcher 对象 收集依赖
针对数组,重写数组的7种方法,调用这7种方法,相当于set 方法,会通知watcher 依赖视图更新。 同时监测observe新增的 数组数据。监测observe数组每一个数据, 调用Object 对象数据劫持流程
-
Vue 3.0
Vue 3.0 改用 Proxy 替代 Object.defineProperty。因为 Proxy 可以直接监听对象和数组的变化
Proxy 监听数据,设置 set 方法 和 get 方法
import { mutableHandlers } from "./baseHandlers"; // 代理相关逻辑
import { isObject } from "./util"; // 工具方法
export function reactive(target) {
// 根据不同参数创建不同响应式对象
return createReactiveObject(target, mutableHandlers);
}
function createReactiveObject(target, baseHandler) {
if (!isObject(target)) {
return target;
}
const observed = new Proxy(target, baseHandler);
return observed;
}
const get = createGetter();
const set = createSetter();
function createGetter() {
return function get(target, key, receiver) {
// 对获取的值进行放射
const res = Reflect.get(target, key, receiver);
console.log("属性获取", key);
if (isObject(res)) {
// 如果获取的值是对象类型,则返回当前对象的代理对象
return reactive(res);
}
return res;
};
}
function createSetter() {
return function set(target, key, value, receiver) {
const oldValue = target[key];
const hadKey = hasOwn(target, key);
const result = Reflect.set(target, key, value, receiver);
if (!hadKey) {
console.log("属性新增", key, value);
} else if (hasChanged(value, oldValue)) {
console.log("属性值被修改", key, value);
}
return result;
};
}
export const mutableHandlers = {
get, // 当获取属性时调用此方法
set, // 当修改属性时调用此方法
};