这次改造方案的目的是让服务端获取到 vuex 里的动态数据,使得在服务端渲染的时候把动态数据也渲染出来
服务端获取到 vuex 里的动态数据之后,再同步到 客户端的 vuex 中。
下面是报错解决:
nprogress
进度条asyncData
只能在路由组件中使用getRoomlist
使用的是 mockjs 接口,所以用的是客户端获取 vuexgetCategoryList
真实接口是服务端获取的!(虽然没啥用…)首先匹配路由组件(无法匹配路由组件中的子组件!!!)
每次刷新页面则对匹配的路由组件调用里面的 asyncData 函数(这里如果是路由跳转则不会调用)
导出的 vuex 的数据 state
import { createApp } from './main'
import { renderToString } from 'vue/server-renderer'
export async function render(url: string) {
const { app, router, store } = createApp()
await router.push(url)
await router.isReady()
// 匹配路由组件
const matchedComponents = router.currentRoute.value.matched.flatMap(record =>
Object.values(record.components)
)
// 对所有匹配的路由组件调用里面的 asyncData 函数
await Promise.all(matchedComponents.map(function(Component) {
if(Component.asyncData) {
// asyncData 函数接收这些参数
return Component.asyncData({ store, route: router.currentRoute })
}
}))
const appHtml = await renderToString(app)
const state = store.state
return { appHtml, state }
}
服务端获取到 vuex 里的动态数据之后,再同步到 客户端的 vuex 中
<body>
<div id="app"><!--ssr-outlet--></div>
<script type="module" src="/src/entry-client.ts"></script>
<script>
window.__INITIAL_STATE__ = '<!--vuex-state-->'
</script>
</body>
在 router.beforeEach
函数前加入
if ((window as any).__INITIAL_STATE__) {
store.replaceState((window as any).__INITIAL_STATE__)
}
获取服务端入口文件导出的 vuex 的数据 state
,并和 html 文档一实现替换效果
// 4. 渲染应用的 HTML。这假设 entry-server.js 导出的 `render`
// 函数调用了适当的 SSR 框架 API。
const { appHtml, state } = await render(url)
// 5. 注入渲染后的应用程序 HTML 到模板占位符中(重点!)
const html = template.replace(`<!--ssr-outlet-->`, appHtml)
.replace('\'<!--vuex-state-->\'', JSON.stringify(state))
asyncData
函数会在路由组件服务端渲染的时候被调用
可惜的是使用这个函数就不能使用 setup
语法糖了!!!!
案例:asyncData 函数初始化 vuex 数据,使服务端和客户端同步获取
<script lang="ts">
import { useStore } from '@/store'
export default ({
setup() {
const store = useStore()
let roomList = store.state.categoryList[0]
return {
roomList
}
},
async asyncData({ store, route }: any) {
await store.dispatch('getCategoryList')
}
})
</script>
<template>
<div>{{ roomList }}</div>
</template>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YbMhEZmU-1677768515026)(mark-img/image-20230228181131199.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CuzXleR8-1677768515029)(mark-img/image-20230228181208631.png)]