You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue.js初始加载JSON为null报错、刷新先出空白页如何解决及代码优化

问题核心结论

你使用this.myData = new Info(data)的赋值方式是完全合理的,属于将业务数据和对应操作封装为类的常用实践,本身没有语法问题,你遇到的报错和这个写法无关,问题出在两个细节上:

  1. 初始渲染时myData为null,模板未加判断就直接调用实例方法导致报错
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 18:24:02