MST

星途 面试题库

面试题:Vue onMounted与onUnmounted在大型项目架构下的优化与设计

在一个大型的Vue项目中,有多个组件频繁地创建和销毁,并且都使用了onMounted和onUnmounted钩子函数进行一些资源的加载与释放操作。随着项目规模的扩大,性能逐渐下降。请阐述你会如何对这些钩子函数的使用进行优化,从架构设计层面提出至少3种优化策略,并结合代码示例说明如何在实际项目中应用这些策略来提升性能和可维护性。
46.8万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

策略一:组件缓存

  1. 原理:使用keep - alive组件缓存频繁创建和销毁的组件,避免重复创建和销毁带来的性能开销。被keep - alive包裹的组件在切换时不会被销毁,而是被缓存起来,再次切换到该组件时,会从缓存中取出并复用。
  2. 代码示例
<template>
  <div>
    <keep - alive>
      <component :is="currentComponent"></component>
    </keep - alive>
    <button @click="changeComponent">切换组件</button>
  </div>
</template>

<script setup>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
import { ref } from 'vue';

const currentComponent = ref(ComponentA);
const changeComponent = () => {
  currentComponent.value = currentComponent.value === ComponentA? ComponentB : ComponentA;
};
</script>
  1. 对性能和可维护性的影响:性能上,减少了组件创建和销毁时onMountedonUnmounted钩子函数的重复执行,提升了切换速度。可维护性方面,代码结构更清晰,对于缓存组件的管理相对简单。

策略二:防抖与节流

  1. 原理:对于onMounted中触发的一些频繁操作(如网络请求),使用防抖或节流技术,避免短时间内多次触发相同操作,减少不必要的资源消耗。防抖是在一定时间内如果再次触发,则重新计时,直到计时结束才执行操作;节流是在一定时间间隔内只允许执行一次操作。
  2. 代码示例
<template>
  <div>
    <input v - model="inputValue" @input="debouncedSearch">
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { debounce } from 'lodash';

const inputValue = ref('');
const search = (value) => {
  // 模拟网络请求
  console.log('Searching:', value);
};
const debouncedSearch = debounce(search, 300);
</script>
  1. 对性能和可维护性的影响:性能上,减少了频繁操作导致的资源浪费,例如网络请求的减少。可维护性方面,通过引入第三方库(如lodash)的防抖和节流函数,代码逻辑更清晰,易于理解和维护。

策略三:合并资源操作

  1. 原理:将多个组件onMounted中相似的资源加载操作合并,在更高层级的组件中统一进行加载,onUnmounted同理,减少重复的资源加载和释放操作。
  2. 代码示例: 假设ComponentAComponentB都需要加载相同的资源
<!-- ParentComponent.vue -->
<template>
  <div>
    <ComponentA :data="sharedData"></ComponentA>
    <ComponentB :data="sharedData"></ComponentB>
  </div>
</template>

<script setup>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';
import { ref, onMounted, onUnmounted } from 'vue';

const sharedData = ref(null);
onMounted(() => {
  // 统一加载资源
  fetch('api/data')
   .then(response => response.json())
   .then(data => {
      sharedData.value = data;
    });
});
onUnmounted(() => {
  // 统一释放资源(如果有需要)
  sharedData.value = null;
});
</script>
<!-- ComponentA.vue -->
<template>
  <div>
    <p>{{ data }}</p>
  </div>
</template>

<script setup>
const props = defineProps({
  data: {
    type: Object
  }
});
</script>
  1. 对性能和可维护性的影响:性能上,减少了重复的资源加载,提高了资源利用效率。可维护性方面,资源加载和释放的逻辑集中在一个地方,便于修改和扩展。

策略四:使用生命周期优化

  1. 原理:对于一些不需要在每次组件创建和销毁时都执行的操作,合理利用其他生命周期钩子函数。例如,对于只需要在组件第一次创建时执行的操作,可以放在created钩子函数中,避免在onMounted中重复执行。
  2. 代码示例
<template>
  <div>
    <p>{{ message }}</p>
  </div>
</template>

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

const message = ref('');
created(() => {
  // 只在组件第一次创建时执行
  message.value = 'Initial message';
});
onMounted(() => {
  // 每次挂载执行的操作
  console.log('Component mounted');
});
</script>
  1. 对性能和可维护性的影响:性能上,减少了onMounted中不必要的重复操作,提升了组件的挂载性能。可维护性方面,明确了不同生命周期钩子函数的职责,使代码逻辑更清晰。