You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 21:45:33