Vue2.0 源码解析 001 之入门 初始化项目

入口文件 index.js

import { initMixin } from "./init";
function Vue(options){
    console.log(options);
    this._init(options)//当用户new vue时 就调用init方法进行vue的初始化方法
}
//  可以拆分逻辑到不同的文件中,更利于代码维护  模块化的概念
initMixin(Vue)
export default Vue

入口文件初始化项目

初始化项目文件 init.js

import { initState } from "./state"

export function initMixin(Vue){
    Vue.prototype._init = function(options){
        console.log('options',options)
        let vm =this
        vm.$options = options//实例上有个 options 表示用户传入的所有属性
        initState(vm)//初始化状态
        // initLifeCycle()//初始化生命周期
    }
    
}

数据处理文件 state.js

import { observe } from "./observe/index";

// VUE 的数据 data watch computed
export function initState(vm) {
    console.log("initState",vm)
  // 将所有数据都定义在vm属性上,并且后续更改 需要触发试图更新
  const opts = vm.$options; //获取用户属性
  if (opts.data) {
    //数据的初始化
    initData(vm);
  }
  if (opts.methods) {
  }
  if (opts.computed) {
  }
  if (opts.watch) {
  }
}

function proxy(vm, source, key) {
  Object.defineProperty(vm, key, {
    get() {
      return vm[source][key];
    },
    set(newValue) {
      vm[source][key] = newValue;
    },
  });
}

function initData(vm) {
  let data = vm.$options.data;
  // 对data类型进行判断    如果式函数  获取函数返回值作为对象
  data = vm._data = typeof data === "function" ? data.call(vm) : data;
  // 观测数据
  //  通过vm._data获取劫持后的数据 用户就可以拿到 _data
   console.log("data",data)
  // 将_data中的数据全部放到vm上
  for (const key in data) {
    proxy(vm, "_data", key);
  }

  observe(data);
}

数据代理

使用 object.defineProperty代理数据,可以直接通过this访问,而不需要this._data访问数据

observe/index.js文件 实现数据的观测

class Observer {
  constructor(value) {
    //需要对这个value属性重新定义
    this.walk(value);
  }
  walk(data) {
    // 将对象中的所有key,重新用defineProperty 定义成响应式的
    console.log("walkData",data)
    Object.keys(data).forEach((key) => {
      defineReactive(data, key, data[key]);
    });
  }
}

export function defineReactive(data, key, value) {
  Object.defineProperty(data, key, {
    get() {
      console.log("get");
      return value;
    },
    set(newValue) {
      console.log("set");
      if (newValue === value) {
        return;
      }
      value = newValue;
    },
  });
}

export function observe(data) {
  console.log(data, "============");
  // 只对对象类型进行观测  非对象无法关测
  if (typeof data !== "object" || data == null) {
    return;
  }
  // 通过类来实现对对象的观测,类可以方便扩展,会产生实例
  return new Observer(data);
}

注解


export function observe(data) {
  console.log(data, "============");
  // 只对对象类型进行观测  非对象无法关测
  if (typeof data !== "object" || data == null) {
    return;
  }
  // 通过类来实现对对象的观测,类可以方便扩展,会产生实例
  return new Observer(data);
}

观测数据时,要先判断观测的数据是不是 对象 ,如果不是对象就停止观测

是对象就 调用 Obsever类进行数据劫持

class Observer {
  constructor(value) {
    //需要对这个value属性重新定义
    this.walk(value);
  }
  walk(data) {
    // 将对象中的所有key,重新用defineProperty 定义成响应式的
    console.log("walkData",data)
    Object.keys(data).forEach((key) => {
      defineReactive(data, key, data[key]);
    });
  }
}

使用  Observer类实现数据的观测,调用definerReactive实现数据的劫持

注解

Object.keys 处理对象,返回以对象的属性键值组成的数组(不包括原型上的属性键值)

想要详细了解 Object.keys用法,请点击

export function defineReactive(data, key, value) {
  Object.defineProperty(data, key, {
    get() {
      console.log("get");
      return value;
    },
    set(newValue) {
      console.log("set");
      if (newValue === value) {
        return;
      }
      value = newValue;
    },
  });
}

Object.defineProperty 用于数据劫持

get和set ,

get用户读取数据,

set 用于设置数据,在数据改边时触发,可用于更新视图

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值