返回介绍

服务器端渲染 SSR

发布于 2024-04-14 00:17:41 字数 3287 浏览 0 评论 0 收藏 0

TIP

如果您使用的是 Nuxt.js, 您需要改为阅读 这些说明

只要您在 setup 函数、gettersactions 的顶部调用 useStore() 函数,使用 Pinia 创建商店应该可以立即用于 SSR:

js
export default defineComponent({
  setup() {
    // 这是有效的,因为 pinia 知道什么应用程序在 `setup()` 中运行
    const main = useMainStore()
    return { main }
  },
})

setup() 之外使用Store

如果您需要在其他地方使用商店,则需要将 pinia 实例 已传递给应用程序 传递给 useStore() 函数调用:

js
const pinia = createPinia()
const app = createApp(App)

app.use(router)
app.use(pinia)

router.beforeEach((to) => {
  // ✅ 这将确保正确的商店用于当前正在运行的应用程序
  const main = useMainStore(pinia)

  if (to.meta.requiresAuth && !main.isLoggedIn) return '/login'
})

Pinia 可以方便地将自身作为 $pinia 添加到您的应用程序中,以便您可以在诸如 serverPrefetch() 之类的函数中使用它:

js
export default {
  serverPrefetch() {
    const store = useStore(this.$pinia)
  },
}

状态补水(hydration)

为了水合初始状态,您需要确保 rootState 包含在 HTML 中的某个位置,以便 Pinia 稍后获取它。 根据您用于 SSR 的内容,出于安全原因,您应该转义状态。 我们建议使用 Nuxt.js 使用的 @nuxt/devalue

js
import devalue from '@nuxt/devalue'
import { createPinia } from 'pinia'
// 检索 rootState 服务器端
const pinia = createPinia()
const app = createApp(App)
app.use(router)
app.use(pinia)

// 渲染页面后,根状态被构建,可以直接在 `pinia.state.value` 上读取。

// 序列化、转义(如果状态的内容可以由用户更改,这非常重要,这几乎总是如此)
// 并将其放置在页面上的某个位置,例如,作为全局变量。

devalue(pinia.state.value)

根据您用于 SSR 的内容,您将设置一个将在 HTML 中序列化的 initial state 变量。 您还应该保护自己免受 XSS 攻击。 例如,使用 vite-ssr 你可以使用 transformState 选项@nuxt/devalue

js
import devalue from '@nuxt/devalue'

export default viteSSR(
  App,
  {
    routes,
    transformState(state) {
      return import.meta.env.SSR ? devalue(state) : state
    },
  },
  ({ initialState }) => {
    // ...
    if (import.meta.env.SSR) {
      // 这将被字符串化并设置为 window.__INITIAL_STATE__
      initialState.pinia = pinia.state.value
    } else {
      // 在客户端,我们恢复状态
      pinia.state.value = initialState.pinia
    }
  }
)

您可以根据需要使用 其他替代方法@nuxt/devalue,例如 如果你可以使用 JSON.stringify()/JSON.parse() 序列化和解析你的状态,你可以大大提高你的性能

使此策略适应您的环境。 确保在客户端调用任何 useStore() 函数之前对 pinia 的状态进行水合。 例如,如果我们将状态序列化为 <script> 标记,以便通过 window.__pinia 在客户端全局访问它,我们可以这样写:

js
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)

// 必须由用户设置
if (isClient) {
  pinia.state.value = JSON.parse(window.__pinia)
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文