nuxt3_使用pinia实现服务器端渲染状态管理
目录
安装nuxt3的pinia包
pnpm i pinia @pinia/nuxt
yarn add pinia @pinia/nuxt
npm i pinia @pinia/nuxt
修改nuxt.config.ts的配置
// nuxt.config.ts
export default defineNuxtConfig({
// ... 其他配置
modules: [
// ...
'@pinia/nuxt',
],
})
在项目中创建pinia仓库
// /stores/index.js
import { defineStore } from 'pinia'
export const useRootStore = defineStore('root', {
state: () => ({
msg: '测试msg数据',
articleData: {
id: undefined,
title: undefined,
content: undefined,
},
}),
getters: {},
})
创建本地的测试服务器用于测试ssr
import express from 'express'
import cors from 'cors'
const article = {
title: 'hello world',
content:
'Eu pariatur aliquip enim enim officia laboris proident adipisicing duis aute ex labore nisi excepteur.',
}
const app = express()
app.use(cors())
app.use(express.json())
app.get('/article', cors(), (req, res) => {
const { id } = req.query
console.log('访问/article ' + new Date().toString())
setTimeout(() => {
res.send({ code: 200, data: { id:Number(id), ...article } })
}, 1500)
})
app.listen(4520, err => {
console.log('server is running at port 4520')
})
在nuxt项目中创建服务器端请求接口
// /server/article.get.js
export default defineEventHandler(async event => {
// console.log(event)
const { id } = getQuery(event)
return new Promise(async (resolve, reject) => {
const res = await $fetch(`http://127.0.0.1:4520/article?id=${id}`).catch(err => err)
if (res.code === 200) {
resolve(res)
} else {
reject(res)
}
})
})
在/article/[id]
路由页面中实现服务器端渲染
// /pages/article/[id].vue
<template>
<div id="articleContainer">
<p>{{ $rootStore?.msg }}</p>
<p>id:{{ $rootStore?.articleData?.id }}</p>
<p>标题:{{ $rootStore?.articleData?.title }}</p>
<p>内容:{{ $rootStore?.articleData?.content }}</p>
</div>
</template>
<script setup>
import { useRootStore } from '~/stores/index'
const articleStore = useArticleStore()
const $route = useRoute()
const $rootStore = useRootStore()
//#region 初始化数据
initData()
async function initData() {
const res = await useFetch(`/api/article?id=${$route.params.id}`)
const res_ = res.data.value
if (res_.code === 200) {
$rootStore.$patch({
articleData: { ...res_.data },
})
}
}
//#endregion
</script>
<style scoped lang="scss"></style>
使用postman向http://localhost:3000/article/95
发送请求
- 注释: localhost:3000是nuxt3项目的默认启动地址
- 得到如下的html结构, 代表服务端渲染成功
<p data-v-inspector="pages/article/[id].vue:3:5">测试msg数据</p>
<p data-v-inspector="pages/article/[id].vue:4:5">id:95</p>
<p data-v-inspector="pages/article/[id].vue:5:5">标题:hello world</p>
<p data-v-inspector="pages/article/[id].vue:6:5">内容:Eu pariatur aliquip enim enim officia laboris proident adipisicing duis aute ex labore nisi excepteur.</p>
修改路由配置实现页面数据缓存
// nuxt.config.ts
routeRules: {
'/article/**': { ssr:true },
},
- 当路由设置为上面所示时, 每次向
/article/[id]
路由发起请求都会重新向服务器调用接口,
// 每次刷新页面服务器接口都会打印请求
访问/article Tue Apr 16 2024 13:21:37 GMT+0800 (中国标准时间)
访问/article Tue Apr 16 2024 13:23:28 GMT+0800 (中国标准时间)
访问/article Tue Apr 16 2024 13:23:30 GMT+0800 (中国标准时间)
- 修改路由配置为
'/article/**': { swr: 60 }, // 页面数据缓存60s, 在缓存数据有效期间不向服务器发起新的请求
- 修改后, 在60s内无论刷新多少次页面, 服务器接口只会打印一条请求
访问/article Tue Apr 16 2024 13:28:53 GMT+0800 (中国标准时间)