Nuxt中useHead结合visibilitychange事件,标签页切回后标题无法恢复如何修复?
问题分析
你当前的代码存在两个核心问题:
- 把
visibilitychange事件监听写在了titleTemplate函数内部,这个函数每次标题更新时都会重复执行,导致绑定多个重复的事件监听;同时函数内的title参数仅在模板首次计算时有效,后续切回标签页时,这个变量已经不是页面的原始标题,所以恢复逻辑失效。 - 没有单独持久化保存页面的原始标题,导致切回标签页时无法获取正确的恢复内容。
修复方案
将事件监听与标题模板逻辑分离,单独保存页面原始标题,确保事件仅绑定一次,且切回时能正确恢复原标题。
方案一:基于路由监听(适合路由配置中包含页面标题的场景)
在layout/default.vue的setup中编写如下代码:
<script setup> import { useHead, useRoute, watch } from 'vue'; import { ref } from 'vue'; // 持久化保存页面原始标题 const originalTitle = ref(''); const route = useRoute(); // 统一设置标题后缀模板 useHead({ titleTemplate: (title) => { const suffix = 'Company suffix'; return title ? `${title} - ${suffix}` : suffix; } }); // 监听路由变化,同步更新原始标题 watch( () => route.meta.title, (newTitle) => { if (newTitle) { originalTitle.value = newTitle; useHead({ title: newTitle }); } }, { immediate: true } ); // 只绑定一次标签页可见性变化事件 document.addEventListener('visibilitychange', () => { if (document.hidden) { useHead({ title: 'Come back' }); } else { useHead({ title: originalTitle.value }); } }); </script>
注意:需要在路由配置中为每个页面添加
meta.title,例如{ path: '/about', name: 'About', meta: { title: 'About us' }, component: () => import('../views/About.vue') }
方案二:直接监听标题变化(适合页面单独用useHead设置标题的场景)
如果你的页面是通过useHead({title: "About us"})单独设置标题,可以用useTitle组合式函数(VueUse或Nuxt内置)来监听和管理标题:
<script setup> import { useHead, useTitle } from '@vueuse/head'; import { ref, watch } from 'vue'; const currentTitle = useTitle(''); const originalTitle = ref(currentTitle.value); // 统一设置标题后缀模板 useHead({ titleTemplate: (title) => { const suffix = 'Company suffix'; return title ? `${title} - ${suffix}` : suffix; } }); // 监听标题变化,仅保存非提示语的原始标题 watch(currentTitle, (newVal) => { if (newVal !== 'Come back') { originalTitle.value = newVal; } }); // 绑定标签页可见性变化事件 document.addEventListener('visibilitychange', () => { if (document.hidden) { currentTitle.value = 'Come back'; } else { currentTitle.value = originalTitle.value; } }); </script>
关键修复点
- 将事件监听从
titleTemplate中移出,避免重复绑定和变量失效问题; - 用单独的变量保存页面原始标题,确保切回标签页时能准确恢复;
- 排除提示语"Come back"对原始标题的污染,避免错误保存提示内容。
内容的提问来源于stack exchange,提问作者kicaj
相关产品推荐
相关产品推荐

