获取vue
项目地址 :https://github.com/vuejs/vue
初始化流程
整体流程
- new Vue()
- init()
- $mount()
- mountComponent
- updateComponent()
- render()
- update()
- new Watcher()
- updateComponent()
- mountComponent
core/index.js
初始化全局api
具体如下:
vue.set = set;
vue.delete = del;
vue.nextTick = nextTick;
initUse(vue) //实现vue.use参数
initMixin(vue)//实现vue.Mixin函数
initExtend(vue)//实现vue.extend函数
initAssetRegister(vue)//注册实现Vue.component/directive/filter
core/instance/init.js
创建组件实例,初始化其数据,属性,事件
initLifecycle(vm) //$parent,$root,$children,$refs
initEvents(vm) //处理父组件传递的事件和回调
initRender(vm) //$slot $scopedSlots _c $createElement
callHook(vm, 'beforeCreate')
initInjections(vm) // 获取注入数据
initState(vm) // 初始化props,methods,data,computed,watch
initProvide(vm) // 提供数据注入
callHook(vm, 'created')
思考一道面试题,谈谈vue的生命周期
- 概念:组件更新,创建,销毁的过程
- 用途:生命周期钩子使我们可以在合适的时间做合适的事情
- 分类列举:
- 初始化过程:beforeCreate Created beforeMounte Mounted
- 更新过程:beforeUpdate,Updated
- 销毁过程:beforeDestory destoryed
- 应用
- created时,所有数据准备就绪,适合做数据获取,赋值等操作
- mounted时,$el已生成,可以获取dom,组件已经挂载,可以访问他们
- updated时,数值变化已经作用于dom,可以获取dom最新状态
- destoryed时,组件实例已销毁,适合做定时器等操作
数据响应式
数据响应式是MVVM框架的一大特点,通过某种策略可以感觉数据变化,Vue2.0中利用了JS语言特性Object.defineReactive(),通过定义对象属性的getter/setter拦截对象属性的访问
具体实现是在Vue初始化时,会调用initState,它会初始化data,props等,
整体流程
initState (vm: Component) src\core\instance\state.js
初始化数据,包括props、methods、data、computed和watch
initData核心代码是将data数据响应化
function initData (vm: Component) {
// 执行数据响应化
observe(data, true /* asRootData */)
}
core/observer/index.js
observe方法返回一个Observer实例
core/observer/index.js
Observer对象根据数据类型执行对应的响应化操作 defineReactive定义对象属性的getter/setter,getter负责添加依赖,setter负责通知更新
core/observer/dep.js
Dep负责管理一组Watcher,包括watcher实例的增删及通知更新
watcher
watcher解析一个表达式并收集依赖,当数值变化时触发回调函数,常用于$watch api和指令
每个组件也会有对应的watcher,数值变化,触发其update函数导致重新渲染
export default class Watcher {
constructor () {}
get () {}
addDep (dep: Dep) {}
update () {}
}
数组响应化
数组数据变化的侦测跟对象不同,我们操作数组通常使用push、pop、splice等方法,此时没有办法得 知数据变化。所以vue中采取的策略是拦截这些方法并通知dep。
src\core\observer\array.js
为数组原型中的7个可以改变内容的方法定义拦截器
Observer中覆盖数组原型
if (Array.isArray(value)) {
// 替换数组原型
protoAugment(value, arrayMethods) // value.__proto__ = arrayMethods
this.observeArray(value)
}