在 Vue 组件中,使用 onMounted
生命周期钩子来添加事件监听器是推荐的做法,因为它确保了 DOM 已经加载完毕,并且组件已经挂载到页面上。将事件监听器直接放在普通的 <script>
标签中可能会导致一些问题,主要原因如下:
1. DOM 加载时机
- 普通
<script>
标签:如果将事件监听器直接放在<script>
标签中,它会在脚本执行时立即运行。此时,DOM 可能还没有完全加载完毕,因此document.getElementById('simple')
可能会返回null
或者未初始化的元素。 - Vue 的
onMounted
钩子:onMounted
钩子会在组件挂载完成后执行,此时 DOM 元素已经可用,可以安全地获取并操作这些元素。
2. 组件生命周期管理
- 普通
<script>
标签:直接在<script>
标签中添加事件监听器,无法与 Vue 组件的生命周期很好地结合。例如,当组件卸载时,你需要手动移除事件监听器,否则会导致内存泄漏。 - Vue 的
onMounted
和onUnmounted
钩子:Vue 提供了onMounted
和onUnmounted
钩子,可以在组件挂载时添加事件监听器,在组件卸载时移除事件监听器,从而避免内存泄漏。
示例代码
以下是一个完整的示例,展示了如何在 Vue 组件中正确地使用 onMounted
和 onUnmounted
来添加和移除事件监听器:
<template>
<div id="simple" ref="chartContainer"></div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import * as echarts from 'echarts';
// 使用 ref 创建一个响应式的图表实例引用
const charts = ref(null);
const chartContainer = ref(null);
onMounted(async () => {
// 确保 DOM 加载完成
await nextTick();
// 初始化 ECharts 实例
charts.value = echarts.init(chartContainer.value);
// 指定图表的配置项和数据
const option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
};
// 设置图表配置
charts.value.setOption(option);
// 监听窗口大小变化,重绘图表
const resizeHandler = () => {
if (charts.value) {
charts.value.resize();
}
};
window.addEventListener('resize', resizeHandler);
// 在 onUnmounted 中移除事件监听器
onUnmounted(() => {
// 销毁 ECharts 实例
if (charts.value) {
charts.value.dispose();
}
// 移除窗口大小变化的事件监听器
window.removeEventListener('resize', resizeHandler);
});
});
</script>
<style scoped>
#simple {
width: 100%;
height: 400px;
}
</style>
关键点总结
- DOM 加载时机:
onMounted
确保 DOM 已经加载完毕。 - 生命周期管理:
onMounted
和onUnmounted
可以更好地管理事件监听器,避免内存泄漏。 - 响应式更新:Vue 的响应式系统和生命周期钩子可以确保在正确的时机执行代码,从而使事件监听器能够正常工作。
通过这种方式,你可以确保事件监听器在适当的时机被添加和移除,从而使图表能够在窗口大小变化时实时更新。