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

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>

错误原因

  1. 组件初始化时,lb变量未赋值,默认值为undefined
  2. Svelte会在组件挂载前渲染DOM,此时lb仍为undefined,模板中尝试访问lb.title直接触发类型错误
  3. 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 20:30:43