面试题答案
一键面试组件渲染优化
- 使用 Fragment
- 策略:Vue 3 支持在组件中返回多个根节点,无需像 Vue 2 那样包裹在一个额外的
<div>
中。这减少了不必要的 DOM 节点,提升渲染性能。 - 示例:在 Vue 2 中,如果组件有多个根节点,需这样写:
在 Vue 3 中,可以直接返回多个根节点:<template> <div> <header></header> <main></main> <footer></footer> </div> </template>
<template> <header></header> <main></main> <footer></footer> </template>
- 策略:Vue 3 支持在组件中返回多个根节点,无需像 Vue 2 那样包裹在一个额外的
- 动态组件的优化
- 策略:在 Vue 3 中,
<keep - alive>
组件有了新的特性。对于动态组件,可以利用<keep - alive>
的include
和exclude
属性,精确控制哪些组件需要被缓存,避免不必要的组件销毁和重建,从而提升性能。 - 示例:假设我们有三个组件
ComponentA
、ComponentB
、ComponentC
,只希望缓存ComponentA
和ComponentB
。
这里<keep - alive :include="['ComponentA', 'ComponentB']"> <component :is="currentComponent"></component> </keep - alive>
currentComponent
是动态切换的组件名。 - 策略:在 Vue 3 中,
数据处理优化
- 响应式系统优化
- 策略:Vue 3 使用 Proxy 替换了 Vue 2 的 Object.defineProperty 来实现响应式系统。在数据量较大时,Proxy 能带来更好的性能。在实际项目中,要注意合理定义响应式数据结构。避免将大量不必要的数据都设置为响应式,只对需要监听变化的数据使用
reactive
或ref
。 - 示例:假设我们有一个大型对象
bigObject
,其中只有部分属性需要响应式。在 Vue 3 中可以这样做:
import { reactive } from 'vue'; const bigObject = { nonReactiveProp: 'This won't be reactive', reactiveProp: 'This will be reactive' }; const reactivePart = reactive({ reactiveProp: bigObject.reactiveProp });
- 策略:Vue 3 使用 Proxy 替换了 Vue 2 的 Object.defineProperty 来实现响应式系统。在数据量较大时,Proxy 能带来更好的性能。在实际项目中,要注意合理定义响应式数据结构。避免将大量不必要的数据都设置为响应式,只对需要监听变化的数据使用
- 计算属性和 Watcher 的优化
- 策略:Vue 3 对计算属性和 Watcher 进行了优化。计算属性缓存机制更高效,Watcher 监听数据变化更精准。在项目中,对于复杂的计算属性,确保其依赖的响应式数据是最小化的,避免不必要的重新计算。对于 Watcher,使用
deep
和immediate
选项时要谨慎,确保只在必要时进行深度监听和立即执行。 - 示例:假设有一个计算属性依赖多个响应式数据,优化前可能这样写:
如果computed: { complexComputed() { return this.data1 + this.data2 + this.data3; } }
data3
很少变化,可以将其从计算属性依赖中分离,通过 Watcher 单独监听:data() { return { data1: 0, data2: 0, data3: 0, result: 0 }; }, computed: { simpleComputed() { return this.data1 + this.data2; } }, watch: { data3(newVal) { this.result = this.simpleComputed + newVal; } }
- 策略:Vue 3 对计算属性和 Watcher 进行了优化。计算属性缓存机制更高效,Watcher 监听数据变化更精准。在项目中,对于复杂的计算属性,确保其依赖的响应式数据是最小化的,避免不必要的重新计算。对于 Watcher,使用
打包构建优化
- Tree - shaking
- 策略:Vue 3 对 ESM 支持更好,在打包构建时,利用 Tree - shaking 特性可以去除未使用的代码,减小包的体积。确保项目使用 ESM 规范导入和导出模块,构建工具(如 Webpack)会自动进行 Tree - shaking。
- 示例:假设项目中有一个工具函数库
utils.js
:
在组件中只使用// utils.js export function add(a, b) { return a + b; } export function subtract(a, b) { return a - b; }
add
函数:
构建时,Webpack 会通过 Tree - shaking 去除未使用的import { add } from './utils.js'; export default { data() { return { num1: 1, num2: 2 }; }, computed: { sum() { return add(this.num1, this.num2); } } };
subtract
函数,减小包体积。 - Code Splitting
- 策略:对于大型 Vue 3 项目,使用 Code Splitting 可以将代码分割成更小的块,按需加载。在路由组件中可以很好地应用这一策略,只有在需要访问某个路由时才加载对应的组件代码。
- 示例:在 Vue Router 配置中,使用动态导入实现 Code Splitting:
这样,import { createRouter, createWebHistory } from 'vue - router'; const router = createRouter({ history: createWebHistory(), routes: [ { path: '/home', component: () => import('./views/Home.vue') }, { path: '/about', component: () => import('./views/About.vue') } ] }); export default router;
Home.vue
和About.vue
的代码在访问对应路由时才会加载,提升了初始加载性能。