Search K
Appearance
Appearance
📊 SEO元描述:2024年最新Vue3 Composition API生命周期教程,详解onMounted、onUpdated、onUnmounted等钩子函数。包含完整实战案例,适合Vue3开发者掌握组件生命周期管理。
核心关键词:Vue3生命周期钩子、onMounted、onUpdated、Composition API生命周期、Vue3组件生命周期
长尾关键词:Vue3生命周期怎么用、onMounted和mounted区别、Vue3生命周期钩子函数、Composition API生命周期管理、Vue3组件初始化
通过本节生命周期钩子,你将系统性掌握:
Composition API生命周期是什么?这是Vue3中组件生命周期管理的新方式。与Options API不同,Composition API将生命周期钩子作为可组合的函数来使用。
💡 设计理念:Composition API的生命周期钩子将组件的时间维度和逻辑维度完美结合,让开发者能够更自然地组织代码。
让我们看看两种API风格的生命周期对比:
// 🎉 Options API生命周期
export default {
data() {
return {
users: [],
loading: false
}
},
beforeCreate() {
console.log('beforeCreate: 实例初始化之后,数据观测之前')
},
created() {
console.log('created: 实例创建完成')
this.fetchUsers()
},
beforeMount() {
console.log('beforeMount: 挂载开始之前')
},
mounted() {
console.log('mounted: 挂载完成')
this.initChart()
},
beforeUpdate() {
console.log('beforeUpdate: 数据更新时调用')
},
updated() {
console.log('updated: 数据更新完成')
},
beforeUnmount() {
console.log('beforeUnmount: 卸载之前')
this.cleanup()
},
unmounted() {
console.log('unmounted: 卸载完成')
},
methods: {
fetchUsers() {
// 获取用户数据
},
initChart() {
// 初始化图表
},
cleanup() {
// 清理资源
}
}
}// 🎉 Composition API生命周期
import {
ref,
onBeforeMount,
onMounted,
onBeforeUpdate,
onUpdated,
onBeforeUnmount,
onUnmounted
} from 'vue'
export default {
setup() {
const users = ref([])
const loading = ref(false)
// 注意:setup函数本身就相当于created
console.log('setup: 相当于created阶段')
const fetchUsers = async () => {
loading.value = true
try {
// 模拟API调用
const response = await fetch('/api/users')
users.value = await response.json()
} finally {
loading.value = false
}
}
const initChart = () => {
// 初始化图表逻辑
console.log('初始化图表')
}
const cleanup = () => {
// 清理资源
console.log('清理资源')
}
// 生命周期钩子
onBeforeMount(() => {
console.log('onBeforeMount: 挂载开始之前')
})
onMounted(() => {
console.log('onMounted: 挂载完成')
initChart()
})
onBeforeUpdate(() => {
console.log('onBeforeUpdate: 数据更新时调用')
})
onUpdated(() => {
console.log('onUpdated: 数据更新完成')
})
onBeforeUnmount(() => {
console.log('onBeforeUnmount: 卸载之前')
cleanup()
})
onUnmounted(() => {
console.log('onUnmounted: 卸载完成')
})
// 在setup中调用数据获取
fetchUsers()
return {
users,
loading,
fetchUsers
}
}
}// 🎉 onMounted实际应用
import { ref, onMounted } from 'vue'
export default {
setup() {
const chartContainer = ref(null)
const chart = ref(null)
onMounted(() => {
// 1. DOM操作
console.log('DOM已挂载,可以安全操作DOM')
// 2. 第三方库初始化
if (chartContainer.value) {
chart.value = new Chart(chartContainer.value, {
type: 'bar',
data: {
labels: ['一月', '二月', '三月'],
datasets: [{
label: '销售额',
data: [12, 19, 3]
}]
}
})
}
// 3. 事件监听器添加
window.addEventListener('resize', handleResize)
// 4. 定时器启动
const timer = setInterval(() => {
console.log('定时任务执行')
}, 5000)
// 5. WebSocket连接
const ws = new WebSocket('ws://localhost:8080')
ws.onopen = () => {
console.log('WebSocket连接已建立')
}
})
const handleResize = () => {
if (chart.value) {
chart.value.resize()
}
}
return {
chartContainer
}
}
}// 🎉 onBeforeUnmount资源清理
import { ref, onMounted, onBeforeUnmount } from 'vue'
export default {
setup() {
const timer = ref(null)
const ws = ref(null)
const eventListeners = ref([])
onMounted(() => {
// 启动定时器
timer.value = setInterval(() => {
console.log('定时任务')
}, 1000)
// 建立WebSocket连接
ws.value = new WebSocket('ws://localhost:8080')
// 添加事件监听器
const resizeHandler = () => console.log('窗口大小改变')
window.addEventListener('resize', resizeHandler)
eventListeners.value.push({
element: window,
event: 'resize',
handler: resizeHandler
})
})
onBeforeUnmount(() => {
// 清理定时器
if (timer.value) {
clearInterval(timer.value)
timer.value = null
}
// 关闭WebSocket连接
if (ws.value) {
ws.value.close()
ws.value = null
}
// 移除事件监听器
eventListeners.value.forEach(({ element, event, handler }) => {
element.removeEventListener(event, handler)
})
eventListeners.value = []
console.log('资源清理完成')
})
return {}
}
}// 🎉 onUpdated数据更新处理
import { ref, nextTick, onUpdated } from 'vue'
export default {
setup() {
const list = ref([])
const scrollContainer = ref(null)
onUpdated(() => {
// 1. DOM更新后的操作
console.log('组件已更新')
// 2. 滚动到底部(聊天应用场景)
nextTick(() => {
if (scrollContainer.value) {
scrollContainer.value.scrollTop = scrollContainer.value.scrollHeight
}
})
// 3. 重新计算布局
recalculateLayout()
// 4. 更新第三方组件
updateThirdPartyComponent()
})
const addItem = (item) => {
list.value.push(item)
}
const recalculateLayout = () => {
// 重新计算布局逻辑
}
const updateThirdPartyComponent = () => {
// 更新第三方组件逻辑
}
return {
list,
scrollContainer,
addItem
}
}
}Composition API允许多次调用同一个生命周期钩子:
// 🎉 多次调用生命周期钩子
import { onMounted, onBeforeUnmount } from 'vue'
// 用户数据管理
function useUserData() {
onMounted(() => {
console.log('用户数据模块初始化')
})
onBeforeUnmount(() => {
console.log('用户数据模块清理')
})
}
// 图表管理
function useChart() {
onMounted(() => {
console.log('图表模块初始化')
})
onBeforeUnmount(() => {
console.log('图表模块清理')
})
}
export default {
setup() {
// 使用多个组合式函数
useUserData()
useChart()
// 组件自身的生命周期
onMounted(() => {
console.log('组件主逻辑初始化')
})
// 所有的onMounted钩子都会按顺序执行
return {}
}
}多次调用的执行顺序:
💼 最佳实践:利用多次调用的特性,可以将不同功能模块的生命周期逻辑分离,提高代码的可维护性和复用性。
// 🎉 生命周期错误处理
import { ref, onMounted, onErrorCaptured } from 'vue'
export default {
setup() {
const error = ref(null)
onMounted(async () => {
try {
// 可能出错的异步操作
await fetchData()
} catch (err) {
error.value = err
console.error('组件初始化失败:', err)
}
})
// 捕获子组件错误
onErrorCaptured((err, instance, info) => {
console.error('捕获到错误:', err)
console.error('错误实例:', instance)
console.error('错误信息:', info)
// 返回false阻止错误继续传播
return false
})
const fetchData = async () => {
// 模拟可能失败的API调用
const response = await fetch('/api/data')
if (!response.ok) {
throw new Error('数据获取失败')
}
return response.json()
}
return {
error
}
}
}通过本节生命周期钩子的学习,你已经掌握:
A: setup函数相当于beforeCreate和created的组合,在组件实例创建之前执行,是Composition API的入口点。
A: 生命周期钩子本身不能是async函数,但可以在钩子内部使用async/await处理异步操作。
A: 可以使用onActivated和onDeactivated钩子,它们专门用于keep-alive组件的激活和停用。
A: 按照注册顺序执行,组合式函数中的钩子优先于组件自身的钩子执行。
A: 使用Vue DevTools查看组件生命周期,在钩子中添加console.log,或使用Vue的性能分析工具。
// 生命周期调试工具
import { getCurrentInstance, onMounted } from 'vue'
export default {
setup() {
const instance = getCurrentInstance()
onMounted(() => {
console.log('组件实例:', instance)
console.log('组件名称:', instance?.type.name)
console.log('组件props:', instance?.props)
})
return {}
}
}"掌握Vue3的生命周期钩子就是掌握了组件的时间维度。记住:在正确的时间做正确的事,这是高质量Vue3应用的基础。"