MST
星途 面试题库

面试题:Vue 跨版本迁移中,如何优雅地处理 beforeDestroy 和 unmounted 钩子的差异

假设你正在将一个 Vue 2.x 项目迁移到 3.x 版本,项目中有大量在 beforeDestroy 钩子中执行的清理逻辑,如解绑事件监听器、取消定时器等。请描述如何在 3.x 版本的 unmounted 钩子中进行等价且优雅的处理,确保迁移过程中功能不受影响,并尽量减少代码的重复。
48.9万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试
  1. 事件监听器解绑
    • 在 Vue 2.x 中,可能会在 beforeDestroy 中这样解绑事件监听器:
    <template>
      <div id="app"></div>
    </template>
    <script>
    export default {
      mounted() {
        window.addEventListener('resize', this.handleResize);
      },
      beforeDestroy() {
        window.removeEventListener('resize', this.handleResize);
      },
      methods: {
        handleResize() {
          // 处理逻辑
        }
      }
    };
    </script>
    
    • 在 Vue 3.x 中,在 unmounted 钩子中做同样的事情:
    <template>
      <div id="app"></div>
    </template>
    <script setup>
    import { onMounted, onUnmounted } from 'vue';
    const handleResize = () => {
      // 处理逻辑
    };
    onMounted(() => {
      window.addEventListener('resize', handleResize);
    });
    onUnmounted(() => {
      window.removeEventListener('resize', handleResize);
    });
    </script>
    
  2. 取消定时器
    • Vue 2.x 中在 beforeDestroy 取消定时器:
    <template>
      <div id="app"></div>
    </template>
    <script>
    export default {
      data() {
        return {
          timer: null
        };
      },
      mounted() {
        this.timer = setInterval(() => {
          // 定时任务逻辑
        }, 1000);
      },
      beforeDestroy() {
        clearInterval(this.timer);
      }
    };
    </script>
    
    • Vue 3.x 中在 unmounted 取消定时器:
    <template>
      <div id="app"></div>
    </template>
    <script setup>
    import { onMounted, onUnmounted } from 'vue';
    let timer;
    onMounted(() => {
      timer = setInterval(() => {
        // 定时任务逻辑
      }, 1000);
    });
    onUnmounted(() => {
      clearInterval(timer);
    });
    </script>
    

为了减少代码重复,可以将一些通用的清理逻辑封装成函数。例如,对于事件监听器的添加和移除,可以封装成一个函数:

const useEventListener = (target, eventName, callback) => {
  const handleCallback = (e) => callback(e);
  onMounted(() => {
    target.addEventListener(eventName, handleCallback);
  });
  onUnmounted(() => {
    target.removeEventListener(eventName, handleCallback);
  });
};

然后在组件中使用:

<template>
  <div id="app"></div>
</template>
<script setup>
import { onMounted, onUnmounted } from 'vue';
const handleResize = () => {
  // 处理逻辑
};
useEventListener(window,'resize', handleResize);
</script>

这样在迁移过程中,对于大量类似的清理逻辑,可以通过这种封装的方式来优雅处理,确保功能不受影响且减少代码重复。