vue2源码浏览分析02

vue

1.组件初始化方法 init

 Vue.prototype._init = function (options) {

/* istanbul ignore if */

if ("development" !== 'production' && config.performance && perf) {

perf.mark('init');

}

var vm = this;

//设置组件唯一ID

vm._uid = uid++;

//设置是vue对象

vm._isVue = true;

if (options && options._isComponent) {

//初始化组件配置$options

initInternalComponent(vm, options);

} else {

// 当options 的属性为 data,components,filter,dereactor,生命周期函数,watch,props,method,computed 会触发 合并策略
    //props,direcotives 转为对象
    // 可以用 optionMergerStrategies 自定义 其他合并策略
    // 合并data options[data]将对象转为一个函数 如果是函数 则返回两个函数的返回obj 如果是对象直接合并对象
    // 生命周期 返回生命周期 函数数组
    // components,filters,dereactors 合并返回新对象
    // watch 返回监控某个的 函数数组
   //

vm.$options = mergeOptions( // 合并 构造函数的 Vue.options 和 options

resolveConstructorOptions(vm.constructor),

options || {},

vm

);

}

/* istanbul ignore else */

{

initProxy(vm);

}

// 扩展_self 为自己

vm._self = vm;
   // 如果有父组件,向父组件 $children push当前组件
   // 将$root = $parent 如果有$parent 不存在 ,根组件本身
   // $children = [],$refs={},_wather=null,_inacitve=null,_directInactive=null,_isMounted=null,_isDestroyed=null,isBeingDestroyed=null

initLifecycle(vm);


   //_event = {},_hasHookEvent = false
   //vm._events 创建_events,并将 _parentListeners 事件添加到 vm._events对象中

    initEvents(vm);

  

initRender(vm); //绑定vm._c 和vm.createElement函数 创建标签

callHook(vm, 'beforeCreate');

initInjections(vm); // resolve injections before data/props

initState(vm);

initProvide(vm); // resolve provide after data/props

callHook(vm, 'created'); // 触发 created方法

/* istanbul ignore if */

if ("development" !== 'production' && config.performance && perf) {

vm._name = formatComponentName(vm, false);

perf.mark('init end');

perf.measure(((vm._name) + " init"), 'init', 'init end');

}

console.log(vm)

if (vm.$options.el) { // 存在el 直接挂载到 el 对象上面

vm.$mount(vm.$options.el);

}

};

initState (vm)

function initState (vm) {

vm._watchers = [];

var opts = vm.$options;
  // 将属性全部转到 vm._props 上面, 并且监听该上面的数据 改变,如果改变的触发所有依赖该数据的 数据

if (opts.props) { initProps(vm, opts.props); }

//绑定方法 将方法绑定到 vm 上面

if (opts.methods) { initMethods(vm, opts.methods); }

if (opts.data) {
  //观察data以及上面的所有数据

initData(vm);

} else {

//得到或者创建一个 Observer 对象

observe(vm._data = {}, true /* asRootData */);

}

//监控 Compuetd 函数和对象,并把他们绑定到vm._computedWatchers上面,get方法执行得到数据

if (opts.computed) { initComputed(vm, opts.computed); }
  //为每一个 watch 创建 watcher对象进行监听

if (opts.watch) { initWatch(vm, opts.watch); }

}

 

//监听器
/*
传入当前组件,需要监听的表达式或者函数,回调函数,参数
当监听的表达式值或者函数发生变化
执行run函数
get函数用于得到当前值
evalute函数与用于重新脏检测
updata函数用于更新所以以来该表达式的数据
*/

var Watcher = function Watcher (vm, expOrFn, cb, options) {

this.vm = vm;

vm._watchers.push(this);

// options

if (options) {

this.deep = !!options.deep;

this.user = !!options.user;

this.lazy = !!options.lazy;

this.sync = !!options.sync;

} else {

this.deep = this.user = this.lazy = this.sync = false;

}

this.cb = cb;

this.id = ++uid$2; // uid for batching

this.active = true;

this.dirty = this.lazy; // for lazy watchers

this.deps = [];

this.newDeps = [];

this.depIds = new _Set();

this.newDepIds = new _Set();

this.expression = expOrFn.toString();

// parse expression for getter

if (typeof expOrFn === 'function') {

this.getter = expOrFn;

} else {

this.getter = parsePath(expOrFn);

if (!this.getter) {

this.getter = function () {};

"development" !== 'production' && warn(

"Failed watching path: \"" + expOrFn + "\" " +

'Watcher only accepts simple dot-delimited paths. ' +

'For full control, use a function instead.',

vm

);

}

}

this.value = this.lazy

? undefined

: this.get();

};
//返回当前的value
/*
方法:
get : 访问器,得到该属性值
addDep(dep) : 添加依赖,将该watcher添加到传入的dep的子依赖列表subs中,将传入的依赖添加到newDeps中。 当前wather 依赖 dep , dep,子列表subs中包含该wather
cleanupDep : 用newDeps更新当前wather的依赖列表deps ,清空newDeps列表
run : 检查wather 的值是否改变,如果改变触发 ck 函数并传入 new,old 值
evaluate : 设置this.value,dirty=false 计算完毕,
depend : 将该 watcher 添加到 需要依赖的 某个列表中
teardown : 从所有依赖列表中移除该wather
update : 如果是函数(lazy) dirty = true, sysc , 检查值是否改变 ,
*/

//队列执行该依赖 watcher 的 数据更新 依次执行 watcher 的 run方法,结束后执行 updated 组件的函数
/*
has当前队列的id 集合
queue 当前队列watcher集合
*/

function queueWatcher (watcher) {

var id = watcher.id;

if (has[id] == null) {

has[id] = true;

if (!flushing) {

queue.push(watcher); //如果wait 就添加到队列

} else {

// if already flushing, splice the watcher based on its id

// if already past its id, it will be run next immediately.

var i = queue.length - 1;

while (i >= 0 && queue[i].id > watcher.id) {

i--;

}

queue.splice(Math.max(i, index) + 1, 0, watcher);

}

// queue the flush

if (!waiting) { //上一个队列完成后 执行

waiting = true;

nextTick(flushSchedulerQueue); //执行队列中的每个一个watcher run方法

}

}

}

 

//组件上面的监听函数,用于监听 函数或者 exp 表达式值变化 , watch 就是调用的该方法  
Vue.prototype.$watch = function (expOrFn, cb, options) { //调用该方法监听某个表达式,返回unwatcher解除监听, expOrFn 的值变化 就执行回调函数 cb

var vm = this;

options = options || {};

options.user = true;

var watcher = new Watcher(vm, expOrFn, cb, options);

if (options.immediate) {

cb.call(vm, watcher.value); //立即执行,新的值

}

return function unwatchFn () { //用于解除绑定

watcher.teardown();

}

};

 

http://www.cnblogs.com/jiebba/p/6575214.html 

http://www.cnblogs.com/jiebba    我的博客,来看吧!

如果有错误,请留言修改下 哦!

以上是 vue2源码浏览分析02 的全部内容, 来源链接: utcz.com/z/379873.html

回到顶部