从vue设计者的角度解释生命周期,并介绍在实际开发中的应用

137 阅读5分钟

从 Vue 设计者的角度解释生命周期

1. 设计初衷

  • 状态管理与资源协调

    • Vue 的生命周期是为了更好地管理组件从创建到销毁的整个过程,确保组件在不同阶段可以进行相应的操作,例如数据的初始化、DOM 的挂载、更新和资源的清理等。这样可以使开发者明确在何时可以进行特定的操作,避免在错误的时间点操作未准备好或已销毁的资源。
  • 性能优化和资源利用

    • 生命周期钩子可以帮助优化性能,例如在 created 或 mounted 阶段请求数据,避免不必要的数据加载;在 beforeDestroy 或 unmounted 阶段释放资源,避免内存泄漏。

2. 生命周期的不同阶段和钩子函数

  • 创建阶段(Creation)

    • beforeCreate

      • 设计意图:这个阶段组件实例刚刚被创建,数据观测和事件 / 生命周期的配置还未完成。在此阶段,只有一些注入的选项可用,datamethods 等还未被初始化。
      • 使用示例:可以在此阶段进行一些不依赖组件数据和方法的操作,如添加全局事件监听器(不过在 Vue 3 中更推荐使用 onMounted 等组合式 API)。
    • created

      • 设计意图:实例已创建完成,完成了数据的观测和事件 / 生命周期的配置,但尚未开始挂载 DOM。在此阶段可以访问 datacomputedmethods 等。
      • 使用示例:可以进行初始数据的获取和操作,如从 API 获取数据,因为此时组件的数据已经是响应式的。
  • 挂载阶段(Mounting)

    • beforeMount

      • 设计意图:在模板编译完成后,即将开始将虚拟 DOM 渲染为真实 DOM 之前调用。可以在这里进行一些操作,如在 DOM 挂载前对数据进行最后的修改。
      • 使用示例:可以根据业务需求,在该阶段对模板数据进行最后的调整,以影响最终的渲染结果。
    • mounted

      • 设计意图:组件已挂载到 DOM 上,在此阶段可以访问组件的 DOM 元素,并且可以进行 DOM 操作。
      • 使用示例:在这个阶段可以操作 DOM 元素,如使用 document.querySelector 进行操作,或者进行一些第三方库的初始化,如初始化图表库。
  • 更新阶段(Updating)

    • beforeUpdate

      • 设计意图:当数据发生变化,虚拟 DOM 重新渲染之前调用。此时可以在更新前获取旧的数据和状态。
      • 使用示例:可以在这个阶段进行数据对比,以确定是否需要更新某些状态,或者执行某些操作,例如根据数据的变化进行额外的计算或修改。
    • updated

      • 设计意图:数据更新导致的 DOM 重新渲染完成后调用。
      • 使用示例:可在此阶段进行 DOM 操作,但要注意避免导致无限更新循环,因为更新操作可能再次触发更新钩子。
  • 销毁阶段(Destruction)

    • beforeDestroy

      • 设计意图:在组件销毁之前调用,此时组件仍然完全可用,可以进行一些清理工作。
      • 使用示例:可以移除事件监听器、取消订阅、清理定时器等,以防止内存泄漏。
    • unmounted

      • 设计意图:组件已经被销毁,此阶段主要用于清理工作,确保所有的资源都被释放。
      • 使用示例:在 Vue 3 中,此阶段是最终的清理阶段,确保彻底释放资源,包括在 mounted 阶段创建的第三方库实例的销毁等。

在实际开发中的应用

1. 数据获取与初始化

  • created 或 mounted 阶段

    • 在 Vue 2 中,通常在 created 或 mounted 阶段进行数据的获取。例如:

收起

vue

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  data() {
    return {
      message: ''
    };
  },
  created() {
    // 从 API 获取数据
    fetch('https://api.example.com/data')
    .then(response => response.json())
    .then(data => {
        this.message = data.message;
      });
  }
};
</script>

在 Vue 3 中,使用组合式 API 的话,可以在 setup 函数中使用 onMounted 进行数据获取:

收起

vue

<template>
  <div>{{ message }}</div>
</template>

<script>
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const message = ref('');
    onMounted(() => {
      fetch('https://api.example.com/data')
      .then(response => response.json())
      .then(data => {
          message.value = data.message;
        });
    });
    return { message };
  }
};
</script>

2. 资源的使用和清理

  • mounted 和 unmounted 阶段

    • 对于需要使用第三方库的组件,在 mounted 阶段进行初始化,在 unmounted 阶段进行销毁。例如,使用 echarts 图表库:

收起

vue

<template>
  <div ref="chartContainer"></div>
</template>

<script>
import * as echarts from 'echarts';
import { onMounted, onUnmounted, ref } from 'vue';

export default {
  setup() {
    const chartContainer = ref(null);
    let chartInstance;

    onMounted(() => {
      chartInstance = echarts.init(chartContainer.value);
      chartInstance.setOption({
        // 图表配置
      });
    });

    onUnmounted(() => {
      if (chartInstance) {
        chartInstance.dispose();
      }
    });

    return { chartContainer };
  }
};
</script>

3. 监听数据变化

  • beforeUpdate 和 updated 阶段

    • 可以在 beforeUpdate 阶段进行数据的比较,在 updated 阶段进行操作。例如,一个组件的 computed 属性不能完全满足需求时,可以使用这些钩子来监听数据更新:

收起

vue

<template>
  <div>{{ formattedData }}</div>
</template>

<script>
export default {
  data() {
    return {
      data: ''
    };
  },
  computed: {
    formattedData() {
      return this.data.toUpperCase();
    }
  },
  beforeUpdate() {
    console.log('Before update:', this.data);
  },
  updated() {
    console.log('Updated:', this.data);
  }
};
</script>

4. 防止内存泄漏

  • beforeDestroy 或 unmounted 阶段

    • 对于需要手动清理的资源,如定时器、事件监听器等,在组件销毁前进行清理。例如:

收起

vue

<template>
  <div></div>
</template>

<script>
import { onBeforeUnmount } from 'vue';

export default {
  setup() {
    let timer;
    onBeforeUnmount(() => {
      if (timer) {
        clearInterval(timer);
      }
    });

    // 开始定时器
    timer = setInterval(() => {
      console.log('定时器操作');
    }, 1000);
  }
};
</script>

Vue 的生命周期为开发者提供了一个清晰的框架,让开发者可以在组件的不同阶段进行适当的操作,以确保组件的正确运行、资源的合理使用和性能的优化。在实际开发中,根据具体的需求和场景,合理使用生命周期钩子可以提高代码的质量和可维护性。,并介绍在实际开发中的应用