Skip to content

初始化 ​

本节目标:理解“初始化”的核心思路,并能把它用于实际开发或面试表达。

vue 默认支持双向绑定:
页面可以修改数据,一般是表单:radio checkbox input textarea
可以监控到数据变化,并且更新视图(单向的)
vue模式,并不是mvvm,vue默认只是做视图的
实现原理:
使用Object.defineProperty:
将数据对象中原有的属性,更改成带有get和set的一个属性;

这样当修改对象属性值时,会触发set方法,我们在其中通知更新视图;

修改src下的index.js文件,主要逻辑: 对原型链进行拓展,对核心vue不断进行扩展

首先声明了Vue构造函数;

接下来调用一系列initXX方法,目的是对Vue构造函数的原型进行扩展;

在Vue原型方法拓展好之后,我们导出Vue;
之后,用户在调用new Vue()时,就会执行Vue构造函数中的代码,

并最终返回一个vue实例,这个实例上有丰富的方法可供使用;

import { initMixin } from "./init";
function Vue(options) {
    this._init(options);
}
// 对原型链进行拓展
initMixin(Vue)
export default Vue;
init.js
主要逻辑:
用使用vm保存this;
将调用new Vue()时传入的参数options记录到实例的$options属性上;
初始化vm实例initState(vm),主要是对用户定义的options中的data进行数据劫持;

判断用户传入的参数options上是否有el属性,如果有,将页面挂载到指定的el元素内部去;

import { initState } from "./state";
export function initMixin(Vue) {
    Vue.prototype._init = function (options) {
        // vm比this更容易理解代表什么
        const vm = this;
        // 将参数option挂载到vm上
        // 这样其它方法也可以方便取到options
        vm.$options = options;
        // vm上有很多数据,所以直接把vm传给方法
        initState(vm);
        if (vm.$options.el) {
            // 如果有元素,页面要挂载
        }
    }
}
state.js
主要逻辑:
取得传入参数即Vue实例上的$options属性,即用户参数;
判断是否有data属性,如果有的话,进行数据初始化,即initData;
export function initState(vm) {
    // 方便地从vm上取想要的数据
    const opts = vm.$options;
    if (opts.data) {
        initData(vm);
    }
}
initData方法
主要逻辑:
先取得参数vm上的data值,并命名为data;

判断data是一个函数还是一个对象,如果是函数,则要调用一下,调用的时候一定要绑定this为vm实例;

对data即用户定义的数据进行劫持;
function initData(vm) {
  // 用户传入的数据
  let data = vm.$options.data;
  // 只有根实例可以data是一个对象
  data = isFunction(data) ? data.call(vm) : data;
  // 需要将data变成响应式的
  // 观测对象中的属性
  observe(data);
}
export function isFunction(val){
    return typeof val == 'function'
}

本站总访问 — 次