Vue中各个生命周期阶段的源码探究--mounted阶段

文本将对Vue的mounted阶段进行解析。使用的测试代码和之前的一样。vue版本v2.5.17-beta.0
测试代码:

<div id="box">
	I love vue
	<ul>
		<li v-for="item in data" @click="logChange(item.NAME,item.AGE)">
			{
  {item.NAME}}
		</li>
	</ul>
</div>
//js
new Vue({
   
	el: '#box',
	data: {
   
		data:[
			{
   NAME:'SDF',AGE:3},
			{
   NAME:'JIKU',AGE:6},
			{
   NAME:'HYF',AGE:3}
		]
	},
	methods: {
   
		logChange: function(name,age) {
   
			console.log(name,age);
		}
	}
	
});

在得到渲染函数后,就可以执行它生成虚节点。这就是在mounted阶段完成的,来看以下代码。
一、创建监听器对象

function mountComponent (
  vm,
  el,
  hydrating
) {
   
  vm.$el = el;
  if (!vm.$options.render) {
   
    vm.$options.render = createEmptyVNode;
    {
   
      /* istanbul ignore if */
      if ((vm.$options.template && vm.$options.template.charAt(0) !== '#') ||
        vm.$options.el || el) {
   
        warn(
          'You are using the runtime-only build of Vue where the template ' +
          'compiler is not available. Either pre-compile the templates into ' +
          'render functions, or use the compiler-included build.',
          vm
        );
      } else {
   
        warn(
          'Failed to mount component: template or render function not defined.',
          vm
        );
      }
    }
  } 
  callHook(vm, 'beforeMount');

  var updateComponent;
  /* istanbul ignore if */
  if ("development" !== 'production' && config.performance && mark) {
   
    updateComponent = function () {
   
      var name = vm._name;
      var id = vm._uid;
      var startTag = "vue-perf-start:" + id;
      var endTag = "vue-perf-end:" + id;

      mark(startTag);
      var vnode = vm._render();
      mark(endTag);
      measure(("vue " + name + " render"), startTag, endTag);

      mark(startTag);
      vm._update(vnode, hydrating);
      mark(endTag);
      measure(("vue " + name + " patch"), startTag, endTag);
    };
  } else {
   
    updateComponent = function () {
   
      vm._update(vm._render(), hydrating);
    };
  }

  // we set this to vm._watcher inside the watcher's constructor
  // since the watcher's initial patch may call $forceUpdate (e.g. inside child
  // component's mounted hook), which relies on vm._watcher being already defined
  new Watcher(vm, updateComponent, noop, {
   
    before: function before () {
   
      if (vm._isMounted) {
   
        callHook(vm, 'beforeUpdate');
      }
    }
  }, true /* isRenderWatcher */);
  hydrating = false;

  // manually mounted instance, call mounted on self
  // mounted is called for render-created child components in its inserted hook
  if (vm.$vnode == null) {
   
    vm._isMounted = true;
    callHook(vm, 'mounted');
  }
  return vm
}

这里通过创建一个监听器Watcher来执行渲染函数。
即:

new Watcher(vm, updateComponent, noop, {
   
    before: function before () {
   
      if (vm._isMounted) {
   
        callHook(vm, 'beforeUpdate');
      }
    }
  }, true /* isRenderWatcher */);

这个监听器函数最终会执行updateComponent回调

updateComponent = function () {
   
 	vm._update(vm._render(), hydrating);
};

二、执行Vue实例的_render函数,并执行渲染函数

Vue.prototype._render = function () {
   
    var vm = this;
    var ref = vm.$options;
    var render = ref.render;
    var _parentVnode = ref._parentVnode;

    // reset _rendered flag on slots for duplicate slot check
    {
   
      for (var key in vm.$slots) {
   
        // $flow-disable-line
        vm.$slots[key]._rendered = false;
      }
    }

    if (_parentVnode) {
   
      vm.$scopedSlots = _parentVnode.data.scopedSlots || emptyObject;
    }

    // set parent vnode. this allows render functions to have access
    // to the data on the placeholder node.
    vm.$vnode = _parentVnode
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值