vue源码 (1.初始化过程_init)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue源码 (1.初始化过程_init)相关的知识,希望对你有一定的参考价值。

参考技术A 1.在init阶段inject 是比 provide更早,比initState(initProps、initMethods、initComputed、initWatch) 都要早,因为vue的组件层级创建父组件created后再去创建子组件,一层一层向下创建的模式,那么inject如果有在上级组件定义provide,那么都会拿得到,而methods、computed、watch也有可能会用到 inject的值,所以需要放在最先初始化。

2.initInjections 原理

3.beforeCreate生命周期为什么不能访问数据,能访问到什么

4.initEvents 事件是挂在父组件执行还是当前组件this.$emit的组件

5.有el选项为什么可以不需要$mount

Vue.js 源码学习笔记 -- 分析前准备 待续

主体

  实例方法归类:

    data     数据方法
    dom     dom方法
    event    事件处理
    lifecycl   生命周期函数

    init 初始化vue页面

  全局方法:

    derectives filters

 

init过程

data : observer deps computed watch

|| watcher

template: fragment [ directive repeat if component transition filter ]

重点:

把数据(Model) 和视图(View) 建立关联


1. 通过observer 对 data 监听, 包括监听data 任何属性变化

2. 把 template 解析成一段 文档对象, 然后解析其中的directive,

  得到每一个指令所依赖的东西 [包括 数据, 和这个数据更新到页面的原始方法 ]


  比如 v-text=‘mess‘ 被解析后

  1. 所依赖的数据项 this.$data.mess data1
  2. 响应视图的更新方法 span.textContent = this.$data.mess fn1

 

3. 通过 watcher 把上述的两部分结合起来, 即把 directive中的依赖 对应 observer;

  这样有数据更新, 就会触发observer, 如果发现数据 data1 有变化,

  就会通知指令 触发 fn1更新视图


整个vm 核心, 就是实现了 observer(观察数据变化)  parser(解析依赖)  watcher(观察到的数据通知指令的执行更新相应页面方法) 这三个东西

 

 

具体实现

 

  

数据监听机制

如何监听某一个对象属性的变化呢?我们很容易想到 Object.defineProperty 这个 API,

为此属性设计一个特殊的 getter/setter,然后在 setter 里触发一个函数,就可以达到监听的效果。

[ ‘push‘, ‘pop‘, ‘shift‘, ‘unshift‘, splice‘, ‘sort‘, ‘reverse‘].forEach(function( method){
 
  var original = arrayProto[method] // Array.prototype.sort

  //数组的方法执行的时候, 会触发下面这个函数
  _.define( arrayMethods, method, function mutator(){

	//先在原生的数组原型方法中按传入的参数执行一遍, 得到结果
	var result = original.apply(this , args);

	var ob = this.__ob__;
	
	var inserted 

	switch (method){
		case ‘push‘: inserted = args ;break
		case ‘unshift‘: inserted = args ; break
		case ‘splice‘: inserted = args.slice(2);
	
	}
	//不解
	if(inserted) ob.observeArray(inserted) 

	ob.notify()

	return result
	
  })
  
})

  

同时 Vue.js 提供了两个额外的“糖方法”  arr.$set[0] = "c"  和 $remove(index) 来弥补这方面限制带来的不便。

个人理解是把这$set 和 $remove 添加到数组原型中,

因为defineproperty可以监听到数组所有原型方法, 包括用户新增的原型方法

所以用户调用$set 的时候, 会被劫持到

 

path 解析器

var path = ‘a.b[1].v‘
var obj = {
a: { b:[ {v:1}, {v:2}, {v:3} ] }
}

parse( obj, path ) // => 2

如何解析 这个字符串 成为 js语句 是关键

vue.js 是通过状态机管理 来实现对路径的解析的

 

 

 

 

 

 

 

 



















以上是关于vue源码 (1.初始化过程_init)的主要内容,如果未能解决你的问题,请参考以下文章

vue源码学习- Vue初始化过程

vue源码学习- Vue初始化过程

Vue源码思维导图-------------Vue 初始化

Vue.js 源码学习笔记 -- 分析前准备 待续

Vue源码解析八

Vue源码思维导图------------Vue选项的合并之$options