在 Nuxt 3 中获取后处理简单的水合不匹配

问题描述 投票:0回答:1

我正在制作一个简单的“电子邮件确认”页面。 它从 URL 获取确认密钥,向 API 发送 POST 请求,该请求返回

true
或不返回任何内容。 如果密钥正确,API 从数据库中删除并返回
true
,以便页面可以显示成功消息:

// pages/confirm/[key].vue

<script setup>
    const route = useRoute();
    const key = route.params.key;

    const confirmed = ref(false);

    try
    {
        const result = await $fetch('/api/confirm', {
            method: 'post',
            body: { key: key },
        });

        confirmed.value = !!result;
    } catch {}
</script>

<template>
        <div v-if="confirmed">Email confirmed!</div>
</template>

问题是,当我在浏览器中使用在 URL 中传递的正确密钥打开页面时,我只能看到“电子邮件已确认”消息几毫秒,然后它就会消失,并在控制台中显示“水合不匹配”警告。

据我了解,Nuxt 在服务器上呈现页面,其中页面有“电子邮件已确认”消息。但是,在有关确认密钥的 API 调用信息从数据库中删除后,当浏览器渲染时,它再次调用 API,这次它得到一个空响应(因为不再有这样的电子邮件确认密钥)并删除成功消息。

我该如何修复它? 也许有一种方法可以只进行一次 API 调用或以某种方式保存其结果? 我是 Nuxt 的新手,我真的不知道如何正确处理这个“双重渲染”的事情......

javascript nuxt.js server-side-rendering client-side nuxtjs3
1个回答
0
投票

最简单的方法是将

pages/confirm/[key].vue
指定为
nuxt.config.ts

中的 CSR 页面组件
export default defineNuxtConfig({
    routeRules: {
        'confirm-key': {
            ssr: false
        }
    }
});

由于页面仅在客户端呈现,因此

$fetch
只会在用户的浏览器中执行


第二种方法是用

useLazyFetch
代替
$fetch
,而且,你需要将
<div>
包裹在
<client-only>

// pages/confirm/[key].vue

<script setup>
    const route = useRoute();
    const key = route.params.key;

    const confirmed = ref(false);

    try
    {
        const result = await useLazyFetch('/api/confirm', {
            method: 'post',
            body: { key: key },
        });

        confirmed.value = !!result;
    } catch {}
</script>

<template>
    <client-only>
        <div v-if="confirmed">Email confirmed!</div>
    </client-only>
</template>
© www.soinside.com 2019 - 2024. All rights reserved.