Svelte组件消费API时出现TypeError错误求助
问题分析与解决:Svelte组件无法读取undefined的
title属性 问题描述
作为Svelte新手(具备其他编程语言基础),已完成以下开发:
- 定义
Book.ts类型接口 - 实现
BookManager.ts数据获取逻辑 - 在
LatestBook.svelte中通过onMount调用API获取数据
控制台能正常打印返回的书籍数据,但页面抛出500错误:TypeError: Cannot read properties of undefined (reading 'title')
相关代码
API返回数据
{"data": [{"id": 1997,"place": 2,"publisher": 4,"bookid": "01997","title": "法律简史——人类制度文明的深层逻辑","author": "桑本谦","region": "中国大陆","copyrighter": null,"translated": 0,"purchdate": "2022-09-29","price": 89,"pubdate": "2022-09-01","printdate": "2022-09-01","ver": "1.1","deco": "普通","kword": 490,"page": 477,"isbn": "978-7-108-07473-7","category": "D909.9","location": null,"intro": "费老推荐。一本好书。","instock": 1,"img": "http://lumen/books/image/01997/桑本谦/法律简史——人类制度文明的深层逻辑/600"}]}
Book.ts代码
export interface Book { id: number, bookid: string, title: string, author: string, img: string, ... }
BookManager.ts代码
import type {Book} from './Book'; export class BookManager { private base="http://lumen"; async getLatestBook(count=1) : Promise<Book[]>{ const uri=this.base+'/books/latest/'+count; const ret=await fetch(uri); const json=await ret.json(); const data=await json['data'] as Book[]; return data; } }
LatestBook.svelte代码
<script lang="ts"> import { BookManager } from "../lib/BookManager"; import type { Book } from "../lib/Book"; import { onMount } from "svelte"; var lb: Book; onMount(async () =>{ const bm=new BookManager(); let lbs=await bm.getLatestBook(1); lb=lbs[0]; console.log(lb); // 此处能正确打印数据 }) </script> <div class="col-md-6 col-lg-4 mb-4 development grid-item"> <a href="#!" class="text-white bg-dark position-relative d-block overflow-hidden card-hover-2"> <img src="../../static/img/projects/1.jpg" alt="{lb.title}" class="w-100 img-zoom" /> <div class="card-hover-2-overlay position-absolute start-0 top-0 w-100 h-100 d-flex px-4 py-5 flex-column justify-content-between"> <div class="card-hover-2-header w-100"> <div class="card-hover-2-title"> <h5 class="fs-4 mb-2">{lb.title}</h5> </div>
错误原因
- 组件初始化时,
lb变量未赋值,默认值为undefined - Svelte会在组件挂载前渲染DOM,此时
lb仍为undefined,模板中尝试访问lb.title直接触发类型错误 onMount中的API调用是异步操作,数据返回并赋值给lb发生在组件挂载后,无法覆盖初始渲染时的undefined状态
修复方案
方案1:条件渲染(推荐)
用Svelte的{#if}指令包裹需要渲染的内容,确保仅当lb存在时才渲染:
<script lang="ts"> // 保持原变量定义不变 var lb: Book; onMount(async () =>{ const bm=new BookManager(); let lbs=await bm.getLatestBook(1); lb=lbs[0]; }) </script> {#if lb} <div class="col-md-6 col-lg-4 mb-4 development grid-item"> <a href="#!" class="text-white bg-dark position-relative d-block overflow-hidden card-hover-2"> <img src="../../static/img/projects/1.jpg" alt="{lb.title}" class="w-100 img-zoom" /> <div class="card-hover-2-overlay position-absolute start-0 top-0 w-100 h-100 d-flex px-4 py-5 flex-column justify-content-between"> <div class="card-hover-2-header w-100"> <div class="card-hover-2-title"> <h5 class="fs-4 mb-2">{lb.title}</h5> </div> </div> </div> </a> </div> {/if}
方案2:可选链操作符
在模板中访问属性时使用?.,避免undefined引发错误:
<img src="../../static/img/projects/1.jpg" alt="{lb?.title}" class="w-100 img-zoom" /> <h5 class="fs-4 mb-2">{lb?.title}</h5>
方案3:初始化默认值
给lb设置符合Book接口的初始值,消除undefined状态:
<script lang="ts"> let lb: Book = { id: 0, bookid: "", title: "", author: "", img: "" // 补充接口中其他属性的默认值 }; // ... 其余代码不变 </script>
内容的提问来源于stack exchange,提问作者TaylorR
相关产品推荐
相关产品推荐

