2024-11-02
温故知新
00

目录

错误代码
错误现象
问题原因
问题解决

错误代码

ts
const ssrLoad = async () => { console.log("ssrLoad"); // SSR 初始化查询单品列表 const { data: res, error } = await useFetch< Result<PagePack<ProductOverview>> >("/api/product/getProductOverviewList", { method: "post", body: queryParam.value, }); if (error.value) { navigateTo("/500"); } if (res.value?.c == 200) { singlePage.value = res.value.d; } else { ElMessage.error(res.value?.m); } }; await ssrLoad();

错误现象

这是我使用 Nuxt3 时写在 <script setup> 中的一段代码,await ssrLoad(); 是为了用于 SSR 渲染页面调用的函数,但由于这么写,导致页面在输入框输入时会自动调用了 getProductOverviewList 接口。

但神奇的是,没有打印console.log("ssrLoad"); 这段日志;但更神奇的是,我去掉 await ssrLoad(); 这行代码就不会出现自动查询的这个现象,这是什么原因你知道吗?

问题原因

经过排查以及咨询 ChatGPT,得知这个问题可能与 Vue 3ref 响应性机制有关。在 Vue 3 中,<script setup> 的内容会在组件初始化时运行一次,并且响应式数据的更新会触发依赖它的计算属性、方法或其他响应式逻辑。因此,最终确定我的代码错误原因是:

queryParam.value 是响应式数据:如果 queryParam 是一个 refreactive 数据,那么当 queryParam.value 在输入框输入时改变时,会重新触发包含 await ssrLoad() 的响应式计算。这意味着任何在 ssrLoad 函数内访问的响应式变量都可能导致副作用。

再结合 没有打印console.log("ssrLoad"); 这段日志 这个神奇的现象,我们可知,当 queryParam.value 的值变化时,响应式触发了 useFetch 这个函数,而不是 ssrLoad 这个函数。

问题解决

由以上问题原因可以得到一个简单的解决方案,那就是修改 queryParam 的定义方式,不再使用响应式数据,如下:

ts
const param = { pageNum: 1, pageSiez: 10 } const queryParam = ref(param); const ssrLoad = async () => { console.log("ssrLoad"); // SSR 初始化查询单品列表 const { data: res, error } = await useFetch< Result<PagePack<ProductOverview>> >("/api/product/getProductOverviewList", { method: "post", body: param, }); if (error.value) { navigateTo("/500"); } if (res.value?.c == 200) { singlePage.value = res.value.d; } else { ElMessage.error(res.value?.m); } }; await ssrLoad();

经过上述修改,将初始条件独立为一个普通常量,不再是响应式的参数,即可解决该问题。

如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:DingDangDog

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!