vue2.x 对象劫持的原理实现

2020-06-16 06:57:18易采站长站整理

</html>

六:编写Vue入口:index.js


// Vue的核心代码 只是Vue的一个声明
import {initMixin} from './init';
function Vue(options){
// 进行Vue的初始化操作
this._init(options);

}
// 通过引入文件的方式 给Vue原型上添加方法
initMixin(Vue); // 给Vue原型上添加一个_init方法
export default Vue

七:编写初始化操作 init.js


import {initState} from './state'
// 在原型上添加一个init方法
export function initMixin(Vue){
// 初始化流程
Vue.prototype._init = function (options) {
// 数据的劫持
const vm = this; // vue中使用 this.$options 指代的就是用户传递的属性
vm.$options = options;

// 初始化状态
initState(vm); // 分割代码
}
}

八:初始化数据


import {observe} from './observer/index.js'
export function initState(vm){
const opts = vm.$options;
// vue的数据来源 属性 方法 数据 计算属性 watch
if(opts.props){
initProps(vm);
}
if(opts.methods){
initMethod(vm);
}
if(opts.data){
initData(vm);
}
if(opts.computed){
initComputed(vm);
}
if(opts.watch){
initWatch(vm);
}
}
function initProps(){}
function initMethod() {}
function initData(vm){
// 数据初始化工作
let data = vm.$options.data; // 用户传递的data
data = vm._data = typeof data === 'function'?data.call(vm):data;
// 对象劫持 用户改变了数据 我希望可以得到通知 =》 刷新页面
// MVVM模式 数据变化可以驱动视图变化
// Object.defineProperty () 给属性增加get方法和set方法
observe(data); // 响应式原理
}
function initComputed(){}
function initWatch(){}

九:书写核心监听功能


// 把data中的数据 都使用Object.defineProperty重新定义 es5
// Object.defineProperty 不能兼容ie8 及以下 vue2 无法兼容ie8版本
import {
isObject
} from '../util/index'
// 后续我可以知道它是不是一个已经观察了的数据 __ob__
class Observer{
constructor(value){ // 仅仅是初始化的操作
// vue如果数据的层次过多 需要递归的去解析对象中的属性,依次增加set和get方法
// 对数组监控
this.walk(value); // 对对象进行观测
}
walk(data){
let keys = Object.keys(data); // [name,age,address]

// 如果这个data 不可配置 直接return
keys.forEach((key)=>{
defineReactive(data,key,data[key]);
})
}
}
function defineReactive(data,key,value){