vue+ts 基础面试题 (四)
目录
在Composition API中使用生命周期钩子
使用生命周期钩子的方法
组件挂载时执行代码
组件更新后执行操作
组件卸载前清理资源
其他生命周期钩子
服务端渲染特定钩子
组合式函数中的使用
注意事项
与Options API对比
onMounted和onUnmounted的使用场景
onMounted 的使用场景
onUnmounted 的使用场景
组合使用的典型场景
自定义一个组合式函数(Composable)并实现鼠标位置跟踪
核心实现步骤
使用示例
性能优化版本
TypeScript支持
注意事项
keep-alive 组件的作用
基本使用示例
结合路由缓存
控制缓存的组件
缓存生命周期钩子
注意事项
在Composition API中使用生命周期钩子
使用生命周期钩子的方法
在Vue 3的Composition API中,生命周期钩子通过onX
形式的函数导入并使用。
import { onMounted, onUpdated, onUnmounted } from 'vue'
组件挂载时执行代码
onMounted
钩子用于在组件挂载完成后执行代码:
onMounted(() => {console.log('组件已挂载')// 在这里可以访问DOM元素或执行初始化操作
})
组件更新后执行操作
onUpdated
钩子在组件因响应式状态变更而更新其DOM树后调用:
onUpdated(() => {console.log('组件已更新')// 可以在这里操作更新后的DOM
})
组件卸载前清理资源
onUnmounted
钩子在组件卸载前调用,适合执行清理操作:
onUnmounted(() => {console.log('组件即将卸载')// 清除定时器、取消事件监听等
})
其他生命周期钩子
Composition API还提供了其他生命周期钩子:
import { onBeforeMount, onBeforeUpdate, onBeforeUnmount, onErrorCaptured } from 'vue'onBeforeMount(() => {// 在组件挂载前执行
})onBeforeUpdate(() => {// 在组件更新前执行
})onBeforeUnmount(() => {// 在组件卸载前执行
})onErrorCaptured((err, instance, info) => {// 捕获来自后代组件的错误
})
服务端渲染特定钩子
对于服务端渲染,有两个专用的生命周期钩子:
import { onServerPrefetch } from 'vue'onServerPrefetch(() => {// 服务端渲染时,在组件实例在服务器上被渲染之前调用
})
组合式函数中的使用
在组合式函数中使用生命周期钩子时,它们会自动绑定到调用它们的组件实例:
function useFeature() {onMounted(() => {// 会绑定到使用该函数的组件})
}
注意事项
生命周期钩子必须在setup()
函数或<script setup>
同步调用,不应在异步回调中注册。如果需要等待异步操作完成后再执行某些操作,可以在钩子内部使用异步函数:
onMounted(async () => {const data = await fetchData()// 使用获取的数据
})
与Options API对比
Composition API的生命周期钩子与Options API的对应关系:
beforeCreate
-> 使用setup()
created
-> 使用setup()
beforeMount
->onBeforeMount
mounted
->onMounted
beforeUpdate
->onBeforeUpdate
updated
->onUpdated
beforeUnmount
->onBeforeUnmount
unmounted
->onUnmounted
errorCaptured
->onErrorCaptured
renderTracked
->onRenderTracked
renderTriggered
->onRenderTriggered
activated
->onActivated
deactivated
->onDeactivated
onMounted和onUnmounted的使用场景
onMounted 的使用场景
onMounted
是 Vue 3 组合式 API 中的一个生命周期钩子,用于在组件挂载到 DOM 后执行代码。适用于需要在 DOM 渲染完成后进行的操作,例如数据获取、DOM 操作或第三方库初始化。
示例代码
import { onMounted } from 'vue';setup() {onMounted(() => {// 获取 DOM 元素const element = document.getElementById('example');console.log('组件已挂载,DOM 元素:', element);// 发起 API 请求fetchData();});
}
onUnmounted 的使用场景
onUnmounted
是 Vue 3 组合式 API 中的另一个生命周期钩子,用于在组件从 DOM 卸载后执行代码。适用于清理操作,例如取消事件监听、清除定时器或释放资源。
示例代码
import { onUnmounted } from 'vue';setup() {const timer = setInterval(() => {console.log('定时器运行中');}, 1000);onUnmounted(() => {// 清除定时器clearInterval(timer);console.log('组件已卸载,定时器已清除');});
}
组合使用的典型场景
当需要在组件挂载时初始化某些功能,并在卸载时清理这些功能时,可以同时使用 onMounted
和 onUnmounted
。
示例代码
import { onMounted, onUnmounted } from 'vue';setup() {const handleScroll = () => {console.log('处理滚动事件');};onMounted(() => {window.addEventListener('scroll', handleScroll);});onUnmounted(() => {window.removeEventListener('scroll', handleScroll);});
}
自定义一个组合式函数(Composable)并实现鼠标位置跟踪
核心实现步骤
创建一个useMousePosition
函数,利用useState
和useEffect
跟踪鼠标坐标
import { useState, useEffect } from 'react'function useMousePosition() {const [position, setPosition] = useState({ x: 0, y: 0 })useEffect(() => {const updatePosition = (e) => {setPosition({ x: e.clientX, y: e.clientY })}window.addEventListener('mousemove', updatePosition)return () => window.removeEventListener('mousemove', updatePosition)}, [])return position
}
使用示例
在组件中直接调用自定义Hook获取实时坐标
function App() {const { x, y } = useMousePosition()return (<div>Mouse position: {x}, {y}</div>)
}
性能优化版本
添加防抖机制减少状态更新频率
import { useState, useEffect, useCallback } from 'react'
import { throttle } from 'lodash'function useMousePosition(throttleTime = 100) {const [position, setPosition] = useState({ x: 0, y: 0 })const updatePosition = useCallback(throttle((e) => {setPosition({ x: e.clientX, y: e.clientY })}, throttleTime),[])useEffect(() => {window.addEventListener('mousemove', updatePosition)return () => {window.removeEventListener('mousemove', updatePosition)updatePosition.cancel()}}, [updatePosition])return position
}
TypeScript支持
为Hook添加类型定义确保类型安全
interface Position {x: numbery: number
}function useMousePosition(): Position {const [position, setPosition] = useState<Position>({ x: 0, y: 0 })// ...其余实现相同
}
注意事项
- 组件卸载时必须清除事件监听防止内存泄漏
- 服务端渲染(SSR)时需要添加typeof window检查
- 高频事件建议配合防抖/节流使用
- 可扩展为返回相对容器坐标而非窗口坐标
keep-alive 组件的作用
<keep-alive>
是 Vue 3 提供的一个内置组件,主要用于缓存动态组件或路由组件的状态,避免重复渲染和销毁。
- 缓存组件实例:通过包裹动态组件或路由视图,避免频繁创建和销毁组件实例,优化性能。
- 保留组件状态:被缓存的组件会保留其数据状态(如表单输入、滚动位置等),切换回来时无需重新初始化。
- 控制缓存策略:支持按需缓存或排除特定组件(通过
include
和exclude
属性)。
基本使用示例
<template><button @click="toggleComponent">切换组件</button><keep-alive><component :is="currentComponent"></component></keep-alive>
</template><script setup>
import { ref } from 'vue';
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';const currentComponent = ref('ComponentA');
const toggleComponent = () => {currentComponent.value = currentComponent.value === 'ComponentA' ? 'ComponentB' : 'ComponentA';
};
</script>
结合路由缓存
<template><router-view v-slot="{ Component }"><keep-alive><component :is="Component" /></keep-alive></router-view>
</template>
控制缓存的组件
通过 include
或 exclude
指定哪些组件需要缓存或排除(匹配组件 name
选项):
<keep-alive include="ComponentA,ComponentB"><component :is="currentComponent" />
</keep-alive>
缓存生命周期钩子
被缓存的组件会触发 activated
(激活)和 deactivated
(停用)钩子:
<script setup>
import { onActivated, onDeactivated } from 'vue';onActivated(() => {console.log('组件被激活');
});onDeactivated(() => {console.log('组件被停用');
});
</script>
注意事项
- 组件需命名:
include
和exclude
依赖组件的name
选项,确保组件已命名。 - 避免滥用:过度缓存可能增加内存占用,建议仅缓存高频切换的组件(如 Tab 页)。
- 动态组件更新:若动态组件的
props
变化,需通过key
强制更新