面试题答案
一键面试created 钩子函数
- 执行时机:在实例创建完成后被立即调用。此时,数据观测 (data observer) 和 event/watcher 事件配置已被初始化,但尚未挂载到 DOM 上。
- 适合完成的任务:常用于初始化数据,比如从本地存储获取数据并赋值给组件数据属性;发起异步请求获取数据,因为此时组件实例已经创建,可操作数据但不会影响 DOM。
mounted 钩子函数
- 执行时机:在实例被挂载到 DOM 后调用。此时,el 被新创建的 vm.$el 替换,并挂载到实例上去了。
- 适合完成的任务:适合操作 DOM,例如初始化第三方插件(如 echarts 图表插件),因为此时 DOM 已经存在;进行一些需要 DOM 元素的计算,比如获取元素的尺寸。
updated 钩子函数
- 执行时机:在数据更新导致的虚拟 DOM 重新渲染和打补丁之后调用。组件的 DOM 已经更新,可执行依赖于 DOM 的操作。
- 适合完成的任务:如果数据变化后需要对 DOM 进行一些特殊处理,可在此处进行。但要避免在此无限循环更新数据,因为 updated 钩子内再次修改数据会再次触发 updated。
destroyed 钩子函数
- 执行时机:在实例销毁后调用。此时,所有的 data、watchers、子组件和事件监听器都已被移除。
- 适合完成的任务:用于清理工作,如清除定时器、解绑自定义事件、取消尚未完成的异步请求等,以防止内存泄漏。
实际组件化项目场景及优化
假设我们有一个新闻列表组件,用于展示新闻数据并提供分页功能。
- created 阶段:
- 在 created 钩子中发起 AJAX 请求获取新闻列表数据。这样在组件创建时就开始获取数据,不会阻塞 DOM 渲染。
created() { this.$http.get('/api/newsList').then(response => { this.newsData = response.data; }); }
- mounted 阶段:
- 当组件挂载到 DOM 后,初始化分页插件(如 vue - pagination - 2)。因为分页插件依赖于 DOM 结构,在 mounted 中初始化能确保 DOM 已准备好。
mounted() { this.$nextTick(() => { this.$refs.pagination.init(); }); }
- updated 阶段:
- 当新闻列表数据更新(比如用户切换分页),如果需要对列表展示进行一些 DOM 特效(如淡入淡出),可在 updated 钩子中实现。
updated() { this.$refs.newsList.classList.add('fade - in'); setTimeout(() => { this.$refs.newsList.classList.remove('fade - in'); }, 500); }
- destroyed 阶段:
- 如果在获取新闻数据时有未完成的请求(如使用 axios,可通过 CancelToken 实现),在组件销毁时取消请求,防止内存泄漏。
data() { return { cancelToken: null }; }, created() { this.cancelToken = new this.$axios.CancelToken(c => { this.cancel = c; }); this.$http.get('/api/newsList', { cancelToken: this.cancelToken }).then(response => { this.newsData = response.data; }); }, destroyed() { this.cancel && this.cancel(); }
通过合理利用这些生命周期钩子函数,我们可以优化组件性能,确保组件在不同阶段执行合适的任务,使组件功能更加完善且高效。