当前位置: 首页 > 知识库问答 >
问题:

前端 - Vue3: 请问是否有方式可以在Bind.vue不显示时候移除掉快捷键的绑定?

单于淇
2025-11-30

我使用了Vue3的项目,

想要使用这个热键绑定插件:
https://github.com/jaywcjlove/hotkeys-js/

我想要实现的效果是,在Tabs内的Bind.vue组件显示时,才有快捷键的使用,在其他组件显示时候(也就是Bind.vue隐藏的时候),没有快捷键的功能。

我当前的代码如下:

<template>
  <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
    <el-tab-pane label="Bind" name="first"><Bind/></el-tab-pane>
    <el-tab-pane label="Unbind" name="second"><Unbind/></el-tab-pane>

  </el-tabs>
</template>

<script lang="ts" setup>
import { ref } from 'vue'

import type { TabsPaneContext } from 'element-plus'
import Unbind from './Unbind.vue'
import Bind from './Bind.vue'


const activeName = ref('first')

const handleClick = (tab: TabsPaneContext, event: Event) => {
  console.log(tab, event)
}
</script>

<style>
.demo-tabs > .el-tabs__content {
  padding: 32px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}
</style>

Bind.vue

<template>
  Bind comp  
</template>

<script lang="ts" setup>

import hotkeys from 'hotkeys-js';
import { onBeforeUnmount, onMounted } from 'vue';


// 定义处理函数,方便在绑定和解绑时使用
const handleF5 = function(event: KeyboardEvent) {
  event.preventDefault()
  alert('点击了F1按键!')
};

// 组件挂载时注册热键
onMounted(() => {
  hotkeys('F1', handleF5);
});

// 组件卸载时取消热键监听
onBeforeUnmount(() => {
  hotkeys.unbind('F1', handleF5);
});


</script>

Unbind.vue

<template>
  Unbind comp   
</template>

<script lang="ts" setup>

</script>

但是效果却是在Unbind.vue展示时候还是可以执行快捷键,请问是否有方式可以在Bind.vue不显示时候移除掉绑定?


Bind.vue 可以使用快捷键:
image.png

Unbind.vue还是可以使用快捷键:
image.png

===

编辑1:
我使用了这2个生命周期方法:onActivated, onDeactivated
但是切换Tabs的时候,发现Bind.vue并没有执行这2个方法(没有打印console.log)。

<template>
  Bind comp  
</template>

<script lang="ts" setup>

import hotkeys from 'hotkeys-js';
//import { onBeforeUnmount, onMounted } from 'vue';
import { onActivated, onDeactivated } from 'vue'


// 定义处理函数,方便在绑定和解绑时使用
const handleF5 = function(event: KeyboardEvent) {
  event.preventDefault()
  alert('点击了F1按键!')
};

// 组件挂载时注册热键
// onMounted(() => {
  // hotkeys('F1', handleF5);
// });

onActivated(() => {
  console.log('onActivated')
  hotkeys('F1', handleF5);
})

// 组件卸载时取消热键监听
onDeactivated(() => {
  console.log('onDeactivated')
  hotkeys.unbind('F1', handleF5);
});


</script>

共有2个答案

姚飞昂
2025-11-30

还有一个 deactivated 的生命周期,有些时候组件并不一定是被卸载,而是缓存隐藏起来。

#缓存实例的生命周期 - KeepAlive | Vue.js

麻昌翰
2025-11-30

要实现只在Bind.vue显示时生效快捷键,而其他组件显示时自动移除绑定,可以通过以下两种方式解决:

方案1:使用 v-if 控制组件生命周期(推荐)

修改父组件的标签页逻辑,在 <el-tab-pane> 中使用 v-if 控制子组件的销毁和重建:

<template>
  <el-tabs v-model="activeName">
    <el-tab-pane label="Bind" name="first">
      <Bind v-if="activeName === 'first'"/> <!-- 关键修改 -->
    </el-tab-pane>
    <el-tab-pane label="Unbind" name="second">
      <Unbind v-if="activeName === 'second'"/> <!-- 关键修改 -->
    </el-tab-pane>
  </el-tabs>
</template>

修改说明:

  1. 通过 v-if="activeName === 'first'" 控制 Bind 组件的显隐
  2. 当切换到其他标签页时,Bind 组件会被销毁,触发其 onBeforeUnmount 钩子
  3. 不需要修改 Bind.vue 内部逻辑,原有卸载逻辑会自动生效

方案2:使用 Vue 生命周期钩子 onDeactivated(需结合 keep-alive)

适合需要保持组件状态的情况:

  1. 修改父组件

    <template>
      <el-tabs v-model="activeName">
     <el-tab-pane label="Bind" name="first">
       <keep-alive>
         <Bind v-if="activeName === 'first'"/>
       </keep-alive>
     </el-tab-pane>
     <!-- Unbind 同理 -->
      </el-tabs>
    </template>
  2. 修改 Bind.vue

    import { onActivated, onDeactivated } from 'vue'
    
    // 移除 onMounted/onBeforeUnmount 钩子
    onActivated(() => {
      hotkeys('F1', handleF5) // 组件激活时绑定
    });
    
    onDeactivated(() => {
      hotkeys.unbind('F1', handleF5) // 组件停用时解绑
    });

两种方案对比:

特点 方案1 (v-if) 方案2 (keep-alive)
组件状态保留 ❌ 每次重建 ✅ 保持状态
快捷键绑定精确控制
需要修改组件数量 只改父组件 需要改父/子组件
内存占用 更低 更高

为什么原始代码无效?

Element Plus 的 <el-tab-pane> 默认使用 display: none 隐藏组件,不会触发 Vue 组件的卸载钩子,导致 onBeforeUnmount 从未执行。

建议选择方案1,只需添加简单的 v-if 条件判断即可完美解决问题。
 类似资料: