Vue.js初始加载JSON为null报错、刷新先出空白页如何解决及代码优化
问题核心结论
你使用this.myData = new Info(data)的赋值方式是完全合理的,属于将业务数据和对应操作封装为类的常用实践,本身没有语法问题,你遇到的报错和这个写法无关,问题出在两个细节上:
- 初始渲染时
myData为null,模板未加判断就直接调用实例方法导致报错 Info类存在重复解析JSON的隐藏bug
具体优化方案
1. 修复Info类的冗余解析逻辑
你在fetch请求中已经调用了await response.json(),这个方法会自动把接口返回的JSON字符串解析为JS对象,Info构造函数中再次调用JSON.parse(Data)属于重复操作:如果接口返回的是标准JSON结构,相当于对JS对象执行JSON.parse,会直接抛出语法错误。你现在功能正常大概率是后端接口返回了嵌套JSON字符串(接口返回值本身是字符串格式的JSON),属于接口设计不规范。
优化后的getInfo.js代码:
export default class Info { constructor(data) { // 优先做类型容错,仅当传入字符串时才解析 let parsedData = data if (typeof data === 'string') { try { parsedData = JSON.parse(data) } catch (e) { parsedData = {} console.error('JSON解析失败', e) } } this.name = parsedData?.name || '' } getName() { // 方法也加默认值容错 return this.name || '未获取到名称' } }
2. 优化渲染逻辑
你添加v-if="myData !== null"的解法是正确的,也可以用更简洁的可选链语法,不需要额外加判断标签,同时可以补充加载状态避免空白页:
<template> <div> <!-- 加载状态提示,替代空白页 --> <div v-if="!myData">数据加载中...</div> <!-- 可选链写法,兼容myData为null的情况 --> <div v-else>{{myData.getName()}}</div> <!-- 错误提示 --> <div v-if="errorMessage" class="error">{{errorMessage}}</div> </div> </template>
注意要在data中声明errorMessage的初始值:
data() { return { data: null, myData: null, errorMessage: '' // 新增错误信息初始值 } }
3. 请求逻辑优化
把fetch请求抽为独立异步方法,同时添加请求取消逻辑,避免组件销毁后还执行赋值导致内存泄漏:
export default { name: 'App', props: { todoID: String, }, data() { return { data: null, myData: null, errorMessage: '', controller: null // 存储请求中断控制器 } }, created() { this.loadData() }, beforeUnmount() { // 组件销毁时中断未完成的请求 this.controller?.abort() }, methods: { async loadData() { this.controller = new AbortController() try { const response = await fetch(`http://localhost/json-end-point/`, { signal: this.controller.signal }) const data = await response.json(); if (!response.ok) { throw new Error((data && data.message) || response.statusText); } this.myData = new Info(data); this.data = data; } catch (error) { // 忽略主动中断的请求报错 if (error.name !== 'AbortError') { this.errorMessage = error.message; console.error("请求失败:", error); } } } } }
内容的提问来源于stack exchange,提问作者Rain Man
相关产品推荐
相关产品推荐

