如何在Nuxt.js 3中创建切换布局不卸载的全局组件?
在Nuxt 3中实现仅初始化一次、切换布局不卸载的全局组件
完全可以实现,下面提供两种适配需求的靠谱方案:
方案一:持久化全局组件(挂载到根组件)
Nuxt 3的app.vue是整个应用的根组件,所有布局切换都在它内部进行,把全局组件放在这里,就能保证只挂载一次,切换布局时不会被卸载。
1. 调整全局组件(components/PusherClient.vue)
<template> <!-- 无需渲染DOM,仅负责初始化Pusher --> </template> <script setup> // 使用useHead加载外部脚本,比模板中用component更符合Nuxt规范 useHead({ script: [ { src: 'https://js.pusher.com/8.0.0/pusher.min.js', body: true, async: true } ] }) onMounted(() => { // 确保Pusher脚本加载完成后再初始化 const initPusher = () => { if (window.Pusher) { const pusher = new window.Pusher('APP_ID', { cluster: 'CLUSTER_ID' }) const channel = pusher.subscribe('notifications-general') // 注意:替换成你实际的事件名称,原代码里的'PATH'是错误的 channel.bind('YOUR_NOTIFICATION_EVENT', function (data) { console.log('收到通知:', data) alert(data.notification.body_en) }) } else { // 脚本未加载完成,延迟重试 setTimeout(initPusher, 100) } } initPusher() }) // 可选:保险起见,组件卸载时断开Pusher连接(放在app.vue里基本不会触发) onUnmounted(() => { if (window.pusher) { window.pusher.disconnect() } }) </script>
2. 在app.vue中引入组件
<template> <!-- 这个组件会随app.vue永久存在,不会被布局切换卸载 --> <PusherClient /> <NuxtLayout> <NuxtPage /> </NuxtLayout> </template> <script setup> import PusherClient from '~/components/PusherClient.vue' </script>
方案二:使用Nuxt客户端插件(更推荐)
对于这种全局初始化逻辑,用Nuxt插件比组件更合适,插件会在客户端首次加载时仅运行一次,生命周期和应用保持一致。
创建plugins/pusher.client.ts(.client.ts后缀确保仅在客户端执行):
export default defineNuxtPlugin(async () => { // 加载Pusher脚本的工具函数 const loadPusherScript = () => { return new Promise<void>((resolve) => { if (window.Pusher) { resolve() return } const script = document.createElement('script') script.src = 'https://js.pusher.com/8.0.0/pusher.min.js' script.async = true script.onload = () => resolve() document.body.appendChild(script) }) } // 初始化Pusher await loadPusherScript() const pusher = new window.Pusher('APP_ID', { cluster: 'CLUSTER_ID' }) const channel = pusher.subscribe('notifications-general') channel.bind('YOUR_NOTIFICATION_EVENT', (data) => { console.log('收到通知:', data) alert(data.notification.body_en) }) // 可选:将pusher实例提供给全局组件使用 return { provide: { pusher } } })
关键注意事项
- 原代码中
channel.bind('PATH'存在语法错误,需要替换为实际的Pusher事件名称,否则无法正常接收通知。 - 无论哪种方案,都要确保Pusher脚本加载完成后再初始化,避免出现
Pusher is not defined的报错。
内容的提问来源于stack exchange,提问作者aryankarim
相关产品推荐
相关产品推荐

