如何在Nuxt.js生成的静态页面中客户端复用数据?
Nuxt.js 2静态站点数据水合问题
我使用Nuxt.js 2构建静态生成网站,通过asyncData函数获取数据并生成页面的流程正常,但页面在浏览器加载后复用数据时,发现数据对象为undefined。举个具体例子:食谱页面需要根据客户端可增减的份数调整食材用量,但客户端访问时this.recipe无法正常访问,代码如下:
data () { return { recipe: null, servings: 0 } }, async asyncData({ params, error, payload, $axios, $config: { graphqlEndpoint } }){ console.log("payload",payload); console.log("params",params) if (payload){ let recipe = payload; recipe.compositions.sort((a,b) => b.quantity - a.quantity); return { recipe: recipe }; } else { if(params.id){ console.log("fetchRecipe", params.id); const res = await $axios({ url: graphqlEndpoint, method: "post", data: { query: queries.getRecipeDetails(params.id), }, }) if(res.data.data && res.data.data.recettes[0]){ let recipe = res.data.data && res.data.data.recettes[0]; recipe.compositions.sort((a,b) => b.quantity - a.quantity); return { recipe: recipe, servings:recipe.yield}; } else{ error({ statusCode: 404, message: 'Page not found' }) } } error({ statusCode: 404, message: 'Page not found' }) } }, computed: { servingsRatio(){ //this.recipe here doesn't exist on the client -> error return this.servings / this.recipe.yield; } }
解决办法
1. 补全payload分支的servings初始化
当前asyncData处理payload时仅返回recipe,未初始化servings,导致客户端水合后servings保持初始值0,且recipe的依赖状态不完整。修改payload分支:
if (payload){ let recipe = payload; recipe.compositions.sort((a,b) => b.quantity - a.quantity); return { recipe: recipe, servings: recipe.yield // 同步初始化份数 }; }
2. 为computed属性添加空值兜底
避免this.recipe为null或undefined时抛出错误,在计算属性中增加判断:
computed: { servingsRatio(){ if (!this.recipe) return 1; // 兜底默认比例,避免报错 return this.servings / this.recipe.yield; } }
3. 确保数据可序列化
Nuxt静态生成时会将asyncData返回的数据序列化到页面的__NUXT__全局变量中,若recipe包含函数、Symbol等不可序列化内容,会导致客户端水合失败。确保recipe是纯JSON对象,所有数据转换逻辑在asyncData中完成。
4. 验证静态页面的数据注入
检查静态生成后的HTML文件,确认页面中存在__NUXT__全局变量,且其中包含recipe和servings的完整数据,确保数据已被正确注入客户端。
内容的提问来源于stack exchange,提问作者Nicolas Bauwens
相关产品推荐
相关产品推荐

