MST

星途 面试题库

面试题:Vue Composition API的代码优化策略之性能提升

在使用Vue Composition API开发项目时,如何通过合理的代码结构和逻辑来优化性能?例如,当一个组件中有多个复杂的计算逻辑,怎样利用Composition API进行拆分和优化,以避免不必要的计算和渲染。请结合实际项目经验,详细说明你的思路和方法。
37.5万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

1. 利用 computed 进行计算属性拆分

  • 原理computed 会缓存计算结果,只有当它依赖的响应式数据发生变化时才会重新计算。
  • 示例:假设在一个电商商品详情组件中,有多个与商品价格相关的复杂计算。
import { ref, computed } from 'vue';

export default {
  setup() {
    const originalPrice = ref(100);
    const discount = ref(0.8);
    const shippingFee = ref(10);

    const discountedPrice = computed(() => originalPrice.value * discount.value);
    const totalPrice = computed(() => discountedPrice.value + shippingFee.value);

    return {
      originalPrice,
      discount,
      shippingFee,
      discountedPrice,
      totalPrice
    };
  }
};
  • 优势:将复杂计算拆分成多个 computed,每个 computed 只关注一个特定的计算逻辑,使得代码逻辑更清晰,并且避免了不必要的重复计算。

2. 使用 watch 进行依赖监听与优化

  • 原理watch 可以监听响应式数据的变化,并在变化时执行相应的回调函数。通过合理配置 watch,可以控制在特定依赖变化时才执行某些操作,而不是每次渲染都执行。
  • 示例:在一个搜索组件中,根据用户输入的关键词进行搜索,并且只有当关键词变化时才发起搜索请求。
import { ref, watch } from 'vue';
import { searchApi } from '@/api';

export default {
  setup() {
    const searchKeyword = ref('');
    const searchResults = ref([]);

    watch(searchKeyword, async (newValue) => {
      if (newValue) {
        const result = await searchApi(newValue);
        searchResults.value = result;
      } else {
        searchResults.value = [];
      }
    });

    return {
      searchKeyword,
      searchResults
    };
  }
};
  • 优势:避免了在每次渲染时都发起搜索请求,只有当关键词变化时才执行搜索逻辑,从而优化了性能。

3. 提取可复用逻辑到自定义 Hook

  • 原理:自定义 Hook 是一个函数,它可以将可复用的逻辑提取出来,在多个组件中使用,同时也有助于拆分复杂组件的逻辑。
  • 示例:假设有多个组件都需要处理分页逻辑。
// usePagination.js
import { ref } from 'vue';

export function usePagination(totalItems, itemsPerPage = 10) {
  const currentPage = ref(1);
  const totalPages = computed(() => Math.ceil(totalItems / itemsPerPage));
  const startIndex = computed(() => (currentPage.value - 1) * itemsPerPage);
  const endIndex = computed(() => Math.min(startIndex.value + itemsPerPage, totalItems));

  const goToPage = (page) => {
    if (page >= 1 && page <= totalPages.value) {
      currentPage.value = page;
    }
  };

  return {
    currentPage,
    totalPages,
    startIndex,
    endIndex,
    goToPage
  };
}
  • 在组件中使用
import { ref } from 'vue';
import { usePagination } from '@/hooks/usePagination';

export default {
  setup() {
    const totalItems = ref(100);
    const { currentPage, totalPages, startIndex, endIndex, goToPage } = usePagination(totalItems.value);

    return {
      totalItems,
      currentPage,
      totalPages,
      startIndex,
      endIndex,
      goToPage
    };
  }
};
  • 优势:提高了代码的复用性,减少了重复代码,同时也将分页逻辑从组件中分离出来,使组件逻辑更加简洁,便于维护和优化。

4. 合理使用 onMountedonUnmounted

  • 原理onMounted 钩子函数在组件挂载后执行,onUnmounted 钩子函数在组件卸载时执行。通过在这些钩子函数中进行必要的初始化和清理操作,可以避免在组件渲染过程中进行不必要的计算和资源占用。
  • 示例:在一个地图组件中,在组件挂载时初始化地图,在组件卸载时销毁地图实例,以释放资源。
import { onMounted, onUnmounted } from 'vue';
import Map from 'map-library';

export default {
  setup() {
    let mapInstance;

    onMounted(() => {
      mapInstance = new Map({
        // 地图初始化配置
      });
    });

    onUnmounted(() => {
      if (mapInstance) {
        mapInstance.destroy();
      }
    });

    return {};
  }
};
  • 优势:确保资源在需要时正确初始化,在不需要时及时释放,优化了组件的性能和资源占用。