Vue组合式API(script setup)中Fetch API空值读取错误求助
问题:Fetch数据时出现"Cannot read properties of null (reading 'activity')"错误,但数据最终能正常显示
我用Vue组合式API的<script setup>写了一个基础Fetch函数学习用法,运行时控制台报错"Cannot read properties of null (reading 'activity')",但页面最后能正常展示获取到的数据,想知道报错原因和解决办法。
我的代码与数据:
脚本代码:
<script setup> import {ref} from 'vue'; const boredInfo = ref(null) function theData(url) { fetch(url) .then(response => response.json()) .then(actualData => { console.log(actualData) boredInfo.value = actualData }) .catch((e) => { console.error('Das ist der Catch Error: ', e) }) return boredInfo } theData('https://www.boredapi.com/api/activity') </script>
模板代码:
<template> <h1>Lets go!</h1> <div> <h1>Aktivität: {{boredInfo.activity}}</h1> </div> </template>
获取到的JSON数据:
{ "activity": "Make your own LEGO creation", "type": "recreational", "participants": 1, "price": 0, "link": "", "key": "1129748", "accessibility": 0.1 }
报错原因
- 初始化时
boredInfo被设为ref(null),页面首次渲染时,Fetch请求还没完成,boredInfo.value还是null,模板里直接访问boredInfo.activity就会触发“读取null的属性”的错误。 - 后续请求完成后,
boredInfo被赋值为完整的JSON对象,Vue的响应式系统会自动更新页面,所以最终能正常显示数据,但首次渲染抛出的错误已经被控制台捕获了。
解决办法
1. 使用可选链操作符(最简单)
在模板里给属性访问加上?.,当boredInfo为null/undefined时,会自动短路,不会尝试读取后续属性:
<template> <h1>Lets go!</h1> <div> <h1>Aktivität: {{boredInfo?.activity}}</h1> </div> </template>
2. 初始化时设为空对象
把boredInfo的初始值从null改成空对象,这样首次渲染时访问activity只会得到undefined,不会报错:
<script setup> import {ref} from 'vue'; const boredInfo = ref({}) // 改为空对象 function theData(url) { fetch(url) .then(response => response.json()) .then(actualData => { console.log(actualData) boredInfo.value = actualData }) .catch((e) => { console.error('Das ist der Catch Error: ', e) }) return boredInfo } theData('https://www.boredapi.com/api/activity') </script>
3. 添加加载状态,条件渲染
定义一个加载状态的ref,在请求完成前显示加载提示,完成后再渲染数据,彻底避免未就绪时访问属性:
<script setup> import {ref} from 'vue'; const boredInfo = ref(null) const isLoading = ref(true) function theData(url) { fetch(url) .then(response => response.json()) .then(actualData => { console.log(actualData) boredInfo.value = actualData isLoading.value = false }) .catch((e) => { console.error('Das ist der Catch Error: ', e) isLoading.value = false }) } theData('https://www.boredapi.com/api/activity') </script> <template> <h1>Lets go!</h1> <div v-if="isLoading">加载中...</div> <div v-else> <h1>Aktivität: {{boredInfo.activity}}</h1> </div> </template>
内容的提问来源于stack exchange,提问作者mikasa
相关产品推荐
相关产品推荐

