接项目创建后续
目录
1.开启服务端渲染模式SSR
在项目根目录底下的nuxt.config.ts中配置:
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
...
ssr: true,
...
})
具体的解释可以看官网给出的关键概念:渲染模式 - 关键概念 - Nuxt 中文文档
2.接口请求配置
在nuxt3项目中的composables文件新增两个文件useClientRequest.ts和useServerRequest.ts
封装的这两种请求都是基于nuxt3提供的请求$fetch和useFetch,具体信息可自行查阅nuxt3官网
1)客户端请求 :
注:此封装虽标注为客户端请求,但是服务端也会执行,等于说会请求两遍。具体可看下面的详细解释,如果不在意后端服务器的资源消耗可忽略。
// /composables/useClientRequest.ts
type FetchType = typeof $fetch
type FetchOptions = Parameters<FetchType>[1]
// 客户端请求
export const useClientRequest = <T = unknown>(url: string, opts?: FetchOptions) => {
const token = useCookie<string | undefined>('_hhj_sso_token')
const runtimeConfig = useRuntimeConfig()
const defaultOptions: FetchOptions = {
baseURL: runtimeConfig.public.baseUrl,
headers: {
Token: token?.value
} as any,
onRequest({ options }: any) {
options.headers = options.headers || {}
if (token.value) {
options.headers.token = token.value
}
}
}
return $fetch<T>(url, { ...defaultOptions, ...opts })
}
2)服务端请求 :
注:此封装的请求虽然只会在服务端请求,客户端无需再次请求,但是服务端请求回的数据会在页面源码中暴露。具体可看下面的详细解释,如果不在意源码大小可忽略。
// /composables/useServerRequest.ts
import { useFetch, type UseFetchOptions } from '#app'
// 服务端请求
export const useServerRequest = <T = unknown>(url: string, opts: UseFetchOptions<T, unknown>) => {
const token = useCookie<string | undefined>('_hhj_sso_token')
const runtimeConfig = useRuntimeConfig()
const defaultOptions: UseFetchOptions<any> = {
baseURL: runtimeConfig.public.baseUrl,
headers: {
Token: token.value
} as any,
onRequest({ options }: any) {
options.headers = options.headers || {}
if (token.value) {
options.headers.token = token.value
}
}
}
return useFetch<T>(url, { ...defaultOptions, ...opts } as any)
}
3.请求代理
在项目根目录底下的nuxt.config.ts中配置:(主要是nitro中的,其他的可在官网自行查阅)
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
...
ssr: true,
devtools: { enabled: true },
features: {
inlineStyles: false
// devLogs: true
},
devServer: {
host: process.env.NUXT_HOST,
port: Number(process.env.NUXT_PORT)
},
nitro: {
// 该配置用于服务端请求转发
routeRules: {
'/server/**': {
proxy: `${process.env.NUXT_API_SERVER_URL}/**`
}
},
compressPublicAssets: true // 启动压缩
},
...
})
4.项目中遇到的问题(两种请求的弊端):
1)使用useClientRequest:
简单新增个aaa页面,使用以下代码:
<script setup lang="ts">
const res = await useClientRequest<any>('navigation/queryTopNavigationMenuPage', {
query: { pplatform: 'PC' }
})
console.log('res----', res)
</script>
<template>
<div>{{ res }}</div>
</template>
<style lang="scss" scoped></style>
可以看到服务端和客户端都有打印,说明执行了两遍,比较影响性能,请求结果如下:
此时把console.log去掉后在页面查看源代码:
源码底部并未出现相关请求回的数据,不会增加页面源码的大小
如果觉得笼统的话可以换种思路,使用下面这段代码(不建议使用):
<script setup lang="ts">
const data = ref<any>()
if (import.meta.server) {
const res = await useClientRequest<any>('navigation/queryTopNavigationMenuPage', {
query: { pplatform: 'PC' }
})
data.value = res
console.log('data----', data.value)
} else {
console.log('data----', data.value)
}
</script>
<template>
<div>{{ data }}</div>
</template>
<style lang="scss" scoped></style>
这样是不是清晰了,执行结果如下:
2)使用 useServerRequest:
还是使用aaa这个页面,换一种写法:
<script setup lang="ts">
const res = await useServerRequest<any>('navigation/queryTopNavigationMenuPage', {
query: { pplatform: 'PC' }
})
console.log('res----', res)
</script>
<template>
<div>{{ res }}</div>
</template>
<style lang="scss" scoped></style>
终端打印如下:
F12打印:
不清晰的话可以使用import.meta.server去验证的,只在服务端执行,客户端不进行重复请求。
但是会在页面源码中留下请求的数据,目前是一个接口,如果页面中接口多,数据大的话,可以想象源码会成倍增长,不利于seo
3)对于id="__NUXT_DATA__"的解释
查阅了相关资料以及AI回答来看,这个是nuxt3框架中用来对服务端数据进行缓存的,会同步给客户端同步使用,避免重复请求,目前没有什么办法能够处理掉
注:兄弟们有什么好的办法能进行服务端一次请求,同步给客户端使用,不重复请求,并且源码中不保留对应数据的话,请联系我!!!!!!
最后不要忘记一件三连哦!
相关文章: