Vue3中disable-devtool路由切换后ref值不更新问题
问题原因分析
你遇到的核心问题是:组件首次初始化时在<script setup>顶层调用DisableDevtool()注册的回调,会捕获当时的isDevToolsOpen、counter等ref实例;当路由跳转导致组件卸载、再返回重新挂载时,组件会创建新的ref实例,但旧的回调依然指向第一次的ref,所以更新的是旧实例的值,新组件无法感知到变化。同时,isLogged这类闭包中的普通变量,也会因为组件重新初始化出现状态不同步的问题。
修复方案
方案1:组件内动态注册回调(适合单组件使用场景)
将DisableDevtool的配置逻辑移到onMounted中,确保每次组件挂载时,回调都绑定当前组件的最新ref和状态:
<script setup> import { ref, onMounted, onUnmounted } from 'vue' import DisableDevtool from 'disable-devtool' import router from '@/router' import { useCreateLog } from '@/composables/controls/useCreateLog' const isDevToolsOpen = ref(false) let devToolsTimeout = null let isLogged = false const counter = ref(0) const { createLog } = useCreateLog() onMounted(() => { // 每次挂载时重新配置,绑定当前组件的状态 DisableDevtool({ isSuspend: false, ondevtoolopen: () => { isDevToolsOpen.value = true counter.value++ if (!isLogged) { createLog('Developer tools opened') isLogged = true } if (!devToolsTimeout) { devToolsTimeout = setTimeout(() => { router.push({ name: 'ProductList' }) }, 5000) } } }) }) onUnmounted(() => { // 清理定时器避免内存泄漏 if (devToolsTimeout) { clearTimeout(devToolsTimeout) devToolsTimeout = null } // 重置组件状态 isLogged = false isDevToolsOpen.value = false // 暂停开发者工具检测 DisableDevtool.isSuspend = true }) </script>
方案2:全局配置+事件监听(适合多组件共用场景)
如果项目中有多个组件需要检测开发者工具状态,建议全局统一配置,通过事件传递状态,避免重复注册冲突:
- 在
main.js中全局初始化:
import DisableDevtool from 'disable-devtool' import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) // 全局配置,通过自定义事件传递状态 DisableDevtool({ ondevtoolopen: () => app.config.globalProperties.$emit('devtool:open'), ondevtoolclose: () => app.config.globalProperties.$emit('devtool:close') }) app.mount('#app')
- 在目标组件中监听事件:
<script setup> import { ref, onMounted, onUnmounted, getCurrentInstance } from 'vue' import router from '@/router' import { useCreateLog } from '@/composables/controls/useCreateLog' const isDevToolsOpen = ref(false) let devToolsTimeout = null let isLogged = false const counter = ref(0) const { createLog } = useCreateLog() const appContext = getCurrentInstance()?.appContext onMounted(() => { DisableDevtool.isSuspend = false // 监听全局开发者工具打开事件 const handleDevtoolOpen = () => { isDevToolsOpen.value = true counter.value++ if (!isLogged) { createLog('Developer tools opened') isLogged = true } if (!devToolsTimeout) { devToolsTimeout = setTimeout(() => { router.push({ name: 'ProductList' }) }, 5000) } } appContext?.config.globalProperties.$on('devtool:open', handleDevtoolOpen) // 卸载时移除监听并清理资源 onUnmounted(() => { appContext?.config.globalProperties.$off('devtool:open', handleDevtoolOpen) if (devToolsTimeout) { clearTimeout(devToolsTimeout) devToolsTimeout = null } isLogged = false isDevToolsOpen.value = false DisableDevtool.isSuspend = true }) }) </script>
内容的提问来源于stack exchange,提问作者Caner
相关产品推荐
相关产品推荐

