Vue生命钩子大冒险:探索组件的每一个呼吸瞬间

111 阅读2分钟

Vue生命钩子全揭秘:从创建到销毁的奇幻之旅

在Vue.js的广阔世界里,生命钩子(Lifecycle Hooks)是组件从创建到销毁整个生命周期中不可或缺的一部分。它们如同探险者手中的地图,指引着组件在各个阶段的行为与表现。本文将带你踏上一场从beforeCreatedestroyed的奇幻之旅,通过具体例子详细解析Vue生命钩子的执行顺序及其作用。

一、启程:beforeCreate与created

beforeCreate:这是组件生命周期中的第一个钩子,此时组件实例刚刚被创建,数据观测(data observer)、事件/侦听器的配置都还未完成,el属性还不存在,datacomputedwatchmethods上的方法和数据都不可被访问。

created:紧随beforeCreate之后,此时组件实例已经创建完成,完成了数据观测、属性和方法的运算,watch/event事件回调配置好了,但是挂载阶段还没开始,$el属性目前不可见。

例子

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue!'
  },
  beforeCreate() {
    console.log('beforeCreate:', this.message); // undefined
  },
  created() {
    console.log('created:', this.message); // Hello Vue!
  }
});

二、启程后的风景:beforeMount与mounted

beforeMount:在挂载开始之前被调用,此时模板编译/挂载过程还没有开始,$el属性仍然不可见,但相关的render函数首次被调用。

mountedel被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子。如果root实例挂载了一个文档内元素,当mounted被调用时vm.$el也在文档内。

例子

<div id="app">{{ message }}</div>

<script>
new Vue({
  el: '#app',
  data: {
    message: 'Mounted!'
  },
  beforeMount() {
    console.log('beforeMount:', document.getElementById('app').textContent); // {{ message }}
  },
  mounted() {
    console.log('mounted:', document.getElementById('app').textContent); // Mounted!
  }
});
</script>

三、深入探索:beforeUpdate与updated

beforeUpdate:数据更新时调用,发生在虚拟DOM打补丁之前。这里适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器。

updated:由于数据更改导致的虚拟DOM重新渲染和打补丁,在这之后会调用这个钩子。当这个钩子被调用时,组件DOM已经更新,所以现在可以执行依赖于DOM的操作。但是要避免更改状态,因为这可能会导致无限更新循环。

例子

new Vue({
  el: '#app',
  data: {
    count: 1
  },
  methods: {
    increment() {
      this.count++;
    }
  },
  beforeUpdate() {
    console.log('beforeUpdate:', this.count); // 更新前的值
  },
  updated() {
    console.log('updated:', this.count); // 更新后的值
  }
});

// 假设在某个地方调用了vm.increment()

四、告别之旅:beforeDestroy与destroyed

beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。

destroyed:Vue实例销毁后调用。调用后,Vue实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也都会被销毁。

例子

let vm = new Vue({
  el: '#app',
  data: {
    a: 1
  },
  beforeDestroy() {
    console.log('beforeDestroy:', this.a); // 1
  },
  destroyed() {
    console.log('destroyed:', this.a); // 1,但此时组件已销毁,无法再访问DOM等
  },
  methods: {
    destroy() {
      vm.$destroy(); // 显式销毁Vue实例
    }
  }
});

// 假设在某个地方调用了vm.destroy()

五、总结

Vue的生命钩子为开发者提供了在组件生命周期各个阶段执行代码的机会,从创建前的准备到销毁后的清理等等。