Ionic数据展示组件 #

一、列表组件(List) #

1.1 基本用法 #

html
<!-- 基本列表 -->
<ion-list>
  <ion-item>
    <ion-label>项目一</ion-label>
  </ion-item>
  <ion-item>
    <ion-label>项目二</ion-label>
  </ion-item>
  <ion-item>
    <ion-label>项目三</ion-label>
  </ion-item>
</ion-list>

1.2 列表项样式 #

html
<!-- 带图标的列表项 -->
<ion-list>
  <ion-item>
    <ion-icon name="mail" slot="start"></ion-icon>
    <ion-label>邮件</ion-label>
  </ion-item>
  <ion-item>
    <ion-icon name="call" slot="start"></ion-icon>
    <ion-label>电话</ion-label>
  </ion-item>
</ion-list>

<!-- 带头像的列表项 -->
<ion-list>
  <ion-item>
    <ion-avatar slot="start">
      <img src="avatar.jpg">
    </ion-avatar>
    <ion-label>
      <h2>用户名</h2>
      <p>用户描述</p>
    </ion-label>
  </ion-item>
</ion-list>

<!-- 带缩略图的列表项 -->
<ion-list>
  <ion-item>
    <ion-thumbnail slot="start">
      <img src="image.jpg">
    </ion-thumbnail>
    <ion-label>
      <h2>标题</h2>
      <p>描述</p>
    </ion-label>
  </ion-item>
</ion-list>

1.3 可滑动列表项 #

html
<ion-list>
  <ion-item-sliding>
    <ion-item>
      <ion-label>可滑动项目</ion-label>
    </ion-item>
    <ion-item-options side="start">
      <ion-item-option color="primary">
        <ion-icon name="archive"></ion-icon>
        归档
      </ion-item-option>
    </ion-item-options>
    <ion-item-options side="end">
      <ion-item-option color="danger">
        <ion-icon name="trash"></ion-icon>
        删除
      </ion-item-option>
      <ion-item-option color="warning">
        <ion-icon name="star"></ion-icon>
        收藏
      </ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>

1.4 分组列表 #

html
<ion-list>
  <ion-item-divider>
    <ion-label>组一</ion-label>
  </ion-item-divider>
  <ion-item>项目1</ion-item>
  <ion-item>项目2</ion-item>
  
  <ion-item-divider>
    <ion-label>组二</ion-label>
  </ion-item-divider>
  <ion-item>项目3</ion-item>
  <ion-item>项目4</ion-item>
</ion-list>

1.5 列表头部 #

html
<ion-list>
  <ion-list-header>
    <ion-label>设置</ion-label>
  </ion-list-header>
  <ion-item>
    <ion-label>通知</ion-label>
    <ion-toggle></ion-toggle>
  </ion-item>
  <ion-item>
    <ion-label>深色模式</ion-label>
    <ion-toggle></ion-toggle>
  </ion-item>
</ion-list>

1.6 动态列表 #

typescript
// 组件
export class MyPage {
  items = [
    { id: 1, name: '项目一', description: '描述一' },
    { id: 2, name: '项目二', description: '描述二' },
    { id: 3, name: '项目三', description: '描述三' }
  ];
  
  deleteItem(item: any) {
    const index = this.items.indexOf(item);
    this.items.splice(index, 1);
  }
}
html
<!-- 模板 -->
<ion-list>
  <ion-item-sliding *ngFor="let item of items">
    <ion-item [routerLink]="['/detail', item.id]">
      <ion-label>
        <h2>{{ item.name }}</h2>
        <p>{{ item.description }}</p>
      </ion-label>
    </ion-item>
    <ion-item-options side="end">
      <ion-item-option color="danger" (click)="deleteItem(item)">
        删除
      </ion-item-option>
    </ion-item-options>
  </ion-item-sliding>
</ion-list>

二、卡片组件(Card) #

2.1 基本用法 #

html
<!-- 基本卡片 -->
<ion-card>
  <ion-card-header>
    <ion-card-title>卡片标题</ion-card-title>
    <ion-card-subtitle>卡片副标题</ion-card-subtitle>
  </ion-card-header>
  <ion-card-content>
    这是卡片内容区域。
  </ion-card-content>
</ion-card>

2.2 带图片的卡片 #

html
<ion-card>
  <ion-img src="image.jpg"></ion-img>
  <ion-card-header>
    <ion-card-title>图片卡片</ion-card-title>
  </ion-card-header>
  <ion-card-content>
    这是带图片的卡片内容。
  </ion-card-content>
</ion-card>

2.3 卡片按钮 #

html
<ion-card>
  <ion-card-header>
    <ion-card-title>操作卡片</ion-card-title>
  </ion-card-header>
  <ion-card-content>
    <p>卡片描述内容</p>
  </ion-card-content>
  <ion-button fill="clear">查看详情</ion-button>
</ion-card>

2.4 卡片列表 #

html
<ion-card *ngFor="let item of items">
  <ion-card-header>
    <ion-card-title>{{ item.title }}</ion-card-title>
  </ion-card-header>
  <ion-card-content>
    {{ item.content }}
  </ion-card-content>
</ion-card>

2.5 社交卡片 #

html
<ion-card>
  <ion-item>
    <ion-avatar slot="start">
      <img src="avatar.jpg">
    </ion-avatar>
    <ion-label>
      <h2>用户名</h2>
      <p>2小时前</p>
    </ion-label>
    <ion-button fill="clear" slot="end">
      <ion-icon name="ellipsis-horizontal"></ion-icon>
    </ion-button>
  </ion-item>
  <ion-img src="post-image.jpg"></ion-img>
  <ion-card-content>
    <p>这是发布的动态内容...</p>
  </ion-card-content>
  <ion-row>
    <ion-col>
      <ion-button fill="clear" expand="block">
        <ion-icon name="heart-outline" slot="start"></ion-icon>
        点赞
      </ion-button>
    </ion-col>
    <ion-col>
      <ion-button fill="clear" expand="block">
        <ion-icon name="chatbubble-outline" slot="start"></ion-icon>
        评论
      </ion-button>
    </ion-col>
    <ion-col>
      <ion-button fill="clear" expand="block">
        <ion-icon name="share-outline" slot="start"></ion-icon>
        分享
      </ion-button>
    </ion-col>
  </ion-row>
</ion-card>

2.6 卡片样式 #

scss
ion-card {
  --background: #ffffff;
  margin: 16px;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  
  ion-card-header {
    padding: 16px;
    
    ion-card-title {
      font-size: 18px;
      font-weight: bold;
      color: #333333;
    }
    
    ion-card-subtitle {
      font-size: 14px;
      color: #999999;
    }
  }
  
  ion-card-content {
    padding: 16px;
    font-size: 14px;
    color: #666666;
  }
}

三、网格组件(Grid) #

3.1 基本用法 #

html
<ion-grid>
  <ion-row>
    <ion-col>
      <div>列1</div>
    </ion-col>
    <ion-col>
      <div>列2</div>
    </ion-col>
    <ion-col>
      <div>列3</div>
    </ion-col>
  </ion-row>
</ion-grid>

3.2 列宽设置 #

html
<ion-grid>
  <ion-row>
    <ion-col size="6">
      <div>占6列</div>
    </ion-col>
    <ion-col size="3">
      <div>占3列</div>
    </ion-col>
    <ion-col size="3">
      <div>占3列</div>
    </ion-col>
  </ion-row>
</ion-grid>

3.3 响应式列宽 #

html
<ion-grid>
  <ion-row>
    <!-- 不同屏幕尺寸不同宽度 -->
    <ion-col size="12" size-sm="6" size-md="4" size-lg="3">
      <div>响应式列</div>
    </ion-col>
    <ion-col size="12" size-sm="6" size-md="4" size-lg="3">
      <div>响应式列</div>
    </ion-col>
    <ion-col size="12" size-sm="6" size-md="4" size-lg="3">
      <div>响应式列</div>
    </ion-col>
    <ion-col size="12" size-sm="6" size-md="4" size-lg="3">
      <div>响应式列</div>
    </ion-col>
  </ion-row>
</ion-grid>

3.4 偏移量 #

html
<ion-grid>
  <ion-row>
    <ion-col size="4" offset="4">
      <div>偏移4列</div>
    </ion-col>
  </ion-row>
  <ion-row>
    <ion-col size="3" offset="3">
      <div>偏移3列</div>
    </ion-col>
    <ion-col size="3">
      <div>正常列</div>
    </ion-col>
  </ion-row>
</ion-grid>

3.5 对齐方式 #

html
<!-- 水平对齐 -->
<ion-grid>
  <ion-row class="ion-justify-content-center">
    <ion-col size="4">
      <div>居中</div>
    </ion-col>
  </ion-row>
  
  <ion-row class="ion-justify-content-end">
    <ion-col size="4">
      <div>右对齐</div>
    </ion-col>
  </ion-row>
  
  <ion-row class="ion-justify-content-around">
    <ion-col size="3">
      <div>分散</div>
    </ion-col>
    <ion-col size="3">
      <div>分散</div>
    </ion-col>
  </ion-row>
</ion-grid>

<!-- 垂直对齐 -->
<ion-grid>
  <ion-row class="ion-align-items-center" style="height: 200px;">
    <ion-col>
      <div>垂直居中</div>
    </ion-col>
  </ion-row>
</ion-grid>

3.6 网格样式 #

scss
ion-grid {
  --ion-grid-padding: 16px;
  --ion-grid-column-padding: 12px;
}

ion-col {
  background: #f5f5f5;
  border: 1px solid #e0e0e0;
  padding: 12px;
  text-align: center;
}

四、虚拟滚动(Virtual Scroll) #

4.1 基本用法 #

html
<ion-content>
  <ion-virtual-scroll [items]="items" [itemHeight]="56">
    <ion-item *virtualItem="let item">
      <ion-label>{{ item.name }}</ion-label>
    </ion-item>
  </ion-virtual-scroll>
</ion-content>

4.2 复杂列表项 #

html
<ion-content>
  <ion-virtual-scroll [items]="items" [itemHeight]="80">
    <ion-item *virtualItem="let item">
      <ion-avatar slot="start">
        <img [src]="item.avatar">
      </ion-avatar>
      <ion-label>
        <h2>{{ item.name }}</h2>
        <p>{{ item.email }}</p>
      </ion-label>
    </ion-item>
  </ion-virtual-scroll>
</ion-content>

4.3 分组虚拟滚动 #

html
<ion-content>
  <ion-virtual-scroll 
    [items]="items" 
    [itemHeight]="getHeight"
    [headerFn]="getHeader">
    
    <ion-item-divider *virtualHeader="let header">
      {{ header }}
    </ion-item-divider>
    
    <ion-item *virtualItem="let item">
      <ion-label>{{ item.name }}</ion-label>
    </ion-item>
  </ion-virtual-scroll>
</ion-content>
typescript
// 组件
export class MyPage {
  items = [
    { name: 'Alice', group: 'A' },
    { name: 'Bob', group: 'B' },
    { name: 'Charlie', group: 'C' }
  ];
  
  getHeight(item: any) {
    return item.isHeader ? 40 : 56;
  }
  
  getHeader(item: any) {
    return item.group;
  }
}

五、无限滚动(Infinite Scroll) #

5.1 基本用法 #

html
<ion-content>
  <ion-list>
    <ion-item *ngFor="let item of items">
      {{ item.name }}
    </ion-item>
  </ion-list>
  
  <ion-infinite-scroll (ionInfinite)="loadMore($event)">
    <ion-infinite-scroll-content 
      loadingSpinner="crescent"
      loadingText="加载更多...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>
typescript
// 组件
export class MyPage {
  items: any[] = [];
  page = 1;
  
  constructor(private api: ApiService) {
    this.loadData();
  }
  
  async loadData() {
    const data = await this.api.getItems(this.page);
    this.items = [...this.items, ...data];
  }
  
  async loadMore(event: any) {
    this.page++;
    await this.loadData();
    event.target.complete();
    
    // 没有更多数据时禁用
    if (this.items.length >= 100) {
      event.target.disabled = true;
    }
  }
}

5.2 无限滚动样式 #

scss
ion-infinite-scroll-content {
  --color: #3880ff;
  min-height: 60px;
}

六、下拉刷新(Refresher) #

6.1 基本用法 #

html
<ion-content>
  <ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
    <ion-refresher-content
      pullingIcon="arrow-down"
      pullingText="下拉刷新"
      refreshingSpinner="crescent"
      refreshingText="刷新中...">
    </ion-refresher-content>
  </ion-refresher>
  
  <ion-list>
    <ion-item *ngFor="let item of items">
      {{ item.name }}
    </ion-item>
  </ion-list>
</ion-content>
typescript
// 组件
export class MyPage {
  items: any[] = [];
  
  async doRefresh(event: any) {
    this.page = 1;
    await this.loadData();
    event.target.complete();
  }
}

6.2 自定义刷新内容 #

html
<ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
  <ion-refresher-content
    pullingIcon="refresh"
    pullingText="下拉刷新"
    refreshingSpinner="dots"
    refreshingText="正在刷新...">
  </ion-refresher-content>
</ion-refresher>

七、幻灯片组件(Slides) #

7.1 基本用法 #

html
<ion-slides pager="true">
  <ion-slide>
    <h1>幻灯片 1</h1>
  </ion-slide>
  <ion-slide>
    <h1>幻灯片 2</h1>
  </ion-slide>
  <ion-slide>
    <h1>幻灯片 3</h1>
  </ion-slide>
</ion-slides>

7.2 自动播放 #

html
<ion-slides 
  [options]="slideOpts"
  (ionSlideDidChange)="onSlideChange($event)">
  <ion-slide>
    <img src="banner1.jpg">
  </ion-slide>
  <ion-slide>
    <img src="banner2.jpg">
  </ion-slide>
  <ion-slide>
    <img src="banner3.jpg">
  </ion-slide>
</ion-slides>
typescript
// 组件
export class MyPage {
  slideOpts = {
    initialSlide: 0,
    speed: 400,
    autoplay: {
      delay: 3000,
      disableOnInteraction: false
    },
    loop: true
  };
  
  onSlideChange(event: any) {
    console.log('幻灯片切换');
  }
}

7.3 幻灯片样式 #

scss
ion-slides {
  height: 200px;
}

ion-slide {
  display: flex;
  align-items: center;
  justify-content: center;
  
  img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

八、完整示例 #

8.1 新闻列表 #

typescript
// 组件
export class NewsPage {
  news: any[] = [];
  page = 1;
  isLoading = false;
  
  constructor(private api: ApiService) {}
  
  ionViewWillEnter() {
    this.loadNews();
  }
  
  async loadNews() {
    this.isLoading = true;
    const data = await this.api.getNews(this.page);
    this.news = [...this.news, ...data];
    this.isLoading = false;
  }
  
  async doRefresh(event: any) {
    this.page = 1;
    this.news = [];
    await this.loadNews();
    event.target.complete();
  }
  
  async loadMore(event: any) {
    this.page++;
    await this.loadNews();
    event.target.complete();
  }
  
  async deleteNews(item: any) {
    const index = this.news.indexOf(item);
    this.news.splice(index, 1);
  }
}
html
<!-- 模板 -->
<ion-header>
  <ion-toolbar>
    <ion-title>新闻列表</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
    <ion-refresher-content></ion-refresher-content>
  </ion-refresher>
  
  <ion-card *ngFor="let item of news" [routerLink]="['/news', item.id]">
    <ion-img [src]="item.image"></ion-img>
    <ion-card-header>
      <ion-card-title>{{ item.title }}</ion-card-title>
      <ion-card-subtitle>{{ item.date }}</ion-card-subtitle>
    </ion-card-header>
    <ion-card-content>
      {{ item.summary }}
    </ion-card-content>
  </ion-card>
  
  <ion-infinite-scroll (ionInfinite)="loadMore($event)">
    <ion-infinite-scroll-content></ion-infinite-scroll-content>
  </ion-infinite-scroll>
</ion-content>

九、总结 #

9.1 组件对比 #

组件 用途 特点
List 列表展示 灵活、可滑动
Card 卡片展示 信息丰富
Grid 网格布局 响应式
Virtual Scroll 大数据列表 性能优化
Infinite Scroll 无限加载 分页加载
Refresher 下拉刷新 更新数据
Slides 幻灯片 轮播展示

9.2 下一步 #

掌握了数据展示组件后,接下来让我们学习 主题与样式,了解Ionic的主题定制!

最后更新:2026-03-28