zoukankan      html  css  js  c++  java
  • vue2源码浏览分析02

    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    我的博客,来看吧!

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

  • 相关阅读:
    基于Docker的Mysql主从复制搭建
    Docker操作命令——查看、停止、删除容器
    Git命令
    未定义数组下标: 0
    zookeeper-3.4.14单机多端口集群搭建
    使用MAT分析dump文件定位程序问题
    intellij idea2019.1中文破解版安装
    vscode打造golang开发环境
    python项目开发环境模块安装记录
    shell用法
  • 原文地址:https://www.cnblogs.com/jiebba/p/6575214.html
Copyright © 2011-2022 走看看