我是一名使用 SSR 构建 SPA 的 Vue 开发人员,但在 Nuxt 领域还是个新手。我现在已经熟悉了这个主题并且知道了一些模式。然而,我的想法围绕着 SSR 和数据获取的一些最佳实践。
Given是一个使用supabase作为后端的SPA。仅开发客户端很容易,我必须通过客户端从 SUPABASE REST API 获取所有数据。
现在 Nuxt 正在引入一个附加层及其 硝基服务器和 api 服务器路由。在这里,我正在努力思考应该把代码放在哪里以及应该使用哪个 api 客户端。为了清楚起见,我给你举个例子:
该应用程序是一个标准的食谱应用程序。假设主页正在显示食谱列表。对于仅客户端 SPA,我将使用我的
supabase-js
中的 Homepage.vue
lib 获取数据。
<script setup lang="ts">
await supabase.from('recipes').select(...)
</script>
据我了解,如果我现在想使用 SSR,我需要使用 nuxt 可组合项来获取数据
$fetch
/useFetch
/useAsyncData
。
<script setup lang="ts">
useFetch("$supabase-server/api/recipes")
</script>
我不能再使用supabase-js 库了。
为了解决这个问题,我可以使用硝基服务器代理此请求:
// server/api/recipes.
export default defineEventHandler(async (event): Promise<Recipe | null> => {
...
await supabase.from('recipes').select(...)
...
})
然后可以在
Homepage.vue
中使用 nuxt 可组合项再次获取。
<script setup lang="ts">
useFetch("$nitro-server/api/recipes")
</script>
那么问题解决了吗?一点也不。在初始请求和渲染之后,我需要再次从客户端获取数据。这是我头上的疙瘩。
最佳实践是什么?还是像往常一样回答:“视情况而定”?
useAsyncData
。
<script setup lang="ts">
const { data } = useAsyncData(async () => {
return await supabase.from('recipes').select(...)
}
</script>
在 SSR 中运行时,这将在返回的 HTML 中序列化响应,并且客户端水合将反序列化它而不是重新发送请求。如果通过客户端导航导航到该页面,则将从浏览器发送请求。
在这种情况下,我认为您不需要担心代理。如果您的 SDK 仅包含节点、您希望将某些令牌或代码保密或者您希望将 SDK 从客户端捆绑包中排除,则代理非常有用。但如果您之前可以从客户端使用supabase SDK,则无需更改。