一、初始化操作的核心钩子
1. created(选项式API)
export default {
data() {
return { user: null };
},
created() {
// 适合初始化数据、发起非DOM操作请求
this.fetchUser();
},
methods: {
async fetchUser() {
const response = await fetch('/api/user');
this.user = await response.json();
}
}
};
2. onMounted(组合式API)
import { onMounted, ref } from 'vue';
export default {
setup() {
const count = ref(0);
const element = ref(null);
onMounted(() => {
// DOM已挂载,可安全操作
element.value = document.getElementById('counter');
element.value.addEventListener('click', increment);
});
function increment() {
count.value++;
}
// 必须返回响应式数据
return { count };
}
};
二、清理操作的核心钩子
1. beforeUnmount(组合式API)
import { onBeforeUnmount } from 'vue';
export default {
setup() {
let timer = null;
onBeforeUnmount(() => {
// 组件销毁前清理资源
clearInterval(timer);
timer = null;
});
// 其他逻辑...
}
};
2. unmounted(选项式API)
export default {
data() {
return { socket: null };
},
created() {
this.socket = new WebSocket('ws://example.com');
},
unmounted() {
// 确保WebSocket连接关闭
if (this.socket) {
this.socket.close();
}
}
};
三、组合式API与选项式API的生命周期映射
阶段 | 选项式API | 组合式API |
---|---|---|
初始化 | created | setup |
挂载前 | beforeMount | onBeforeMount |
挂载后 | mounted | onMounted |
更新前 | beforeUpdate | onBeforeUpdate |
更新后 | updated | onUpdated |
销毁前 | beforeDestroy/unmounted | onBeforeUnmount/onUnmounted |
销毁后 | destroyed | 已被移除 |
四、日常开发建议
1. 数据请求策略
// 推荐:created中发起请求,避免阻塞渲染
created() {
this.loadData();
},
methods: {
async loadData() {
try {
this.data = await fetchData();
} catch (error) {
console.error('数据加载失败:', error);
}
}
}
2. DOM操作规范
// 错误示例:在created中操作未挂载的DOM
created() {
this.$refs.container.style.color = 'red'; // this.$refs为null
}
// 正确示例:在mounted中操作
mounted() {
this.$refs.container.style.color = 'red';
}
3. 资源清理守则
// 必须成对出现:添加/移除事件监听
mounted() {
window.addEventListener('resize', this.handleResize);
},
beforeUnmount() {
window.removeEventListener('resize', this.handleResize);
}
五、实战注意事项
1. 父子组件生命周期顺序
父 beforeMount -> 子 beforeMount -> 子 mounted -> 父 mounted
父 beforeUnmount -> 子 beforeUnmount -> 子 unmounted -> 父 unmounted
2. 异步操作处理
// 错误示例:未处理异步清理
onMounted(() => {
this.timer = setInterval(() => {}, 1000);
});
// 正确示例:使用异步清理
onMounted(async () => {
const data = await longRunningTask();
this.data = data;
this.cleanup = () => clearInterval(this.timer);
});
onBeforeUnmount(() => {
if (this.cleanup) this.cleanup();
});
3. 服务端渲染(SSR)兼容
// 避免在beforeMount中执行DOM操作
onBeforeMount(() => {
if (typeof window !== 'undefined') {
// 仅在客户端执行
this.initChart();
}
});
六、典型错误案例分析
1. 忘记清理定时器
mounted() {
this.timer = setInterval(() => {}, 1000); // ❌ 未清理
}
2. 在beforeDestroy中执行复杂计算
beforeDestroy() {
// ❌ 阻塞销毁流程
this.heavyComputation();
}
七、最佳实践总结
- 初始化顺序:created(数据)→ mounted(DOM)
- 清理原则:谁创建谁销毁,成对出现
- 性能优化:避免在mounted中进行重计算
- 错误边界:使用errorCaptured钩子捕获子组件错误
- 状态管理:结合Vuex/Pinia时,优先在created中初始化状态
通过合理运用生命周期钩子,开发者可以实现组件生命周期的精细控制。在实际开发中,建议结合TypeScript的类型系统增强生命周期钩子的类型安全,并利用Vue Devtools进行生命周期调试。