Skip to content

xtf-list

组件说明

xtf-list 是基于 xtf-cell 的列表容器,适用于设置项、消息收件箱和待办清单。它支持扁平或分组数据、单元格侧滑操作、开关回调、加载更多,以及头部、分组和列表项插槽定制。


基础用法

1. 基础列表

使用 items 传入扁平列表,监听 item-click 处理点击:

vue
<template>
  <xtf-list :items="items" section-title="账户设置" @item-click="handleItemClick" />
</template>

<script>
export default {
  data() {
    return {
      items: [
        { title: '手机号', value: '138****1234', arrow: true },
        { title: '收货地址', value: '3 个地址', arrow: true }
      ]
    }
  },
  methods: {
    handleItemClick(payload) {
      console.log('点击列表项:', payload.item.title, payload.index)
    }
  }
}
</script>

2. 分组与开关

使用 groups 描述多个分组;每个 items 项可直接使用 xtf-cell 支持的字段:

vue
<template>
  <xtf-list grouped :groups="groups" @switch-change="handleSwitchChange" />
</template>

<script>
export default {
  data() {
    return {
      groups: [
        {
          title: '通知',
          desc: '接收业务提醒',
          items: [
            { title: '订单提醒', switchable: true, checked: true },
            { title: '营销通知', switchable: true, checked: false }
          ]
        },
        { title: '其他', items: [{ title: '清除缓存', value: '12 MB', arrow: true }] }
      ]
    }
  },
  methods: {
    handleSwitchChange(payload) {
      payload.item.checked = payload.checked
      console.log('开关状态:', payload.item.title, payload.checked)
    }
  }
}
</script>

3. 侧滑操作与加载更多

为列表项配置 swipeActions,并以 loadMore="more" 显示可点击的加载入口:

vue
<template>
  <xtf-list
    :items="orders"
    :load-more="loadStatus"
    @swipe-action="handleSwipeAction"
    @load-more="loadMore"
    @retry-load-more="loadMore"
  />
</template>

<script>
export default {
  data() {
    return {
      loadStatus: 'more',
      orders: [
        {
          title: '订单 #A1029',
          value: '待确认',
          swipeActions: [
            { text: '置顶', color: '#4f46e5' },
            { text: '删除', color: '#ef4444' }
          ]
        }
      ]
    }
  },
  methods: {
    handleSwipeAction(payload) {
      console.log('侧滑操作:', payload.action.text, payload.item.title, payload.index)
    },
    loadMore() {
      this.loadStatus = 'loading'
      setTimeout(() => {
        this.orders.push({ title: '订单 #A1030', value: '待发货' })
        this.loadStatus = 'finished'
        console.log('已加载更多订单')
      }, 500)
    }
  }
}
</script>

4. 自定义列表项插槽

使用 item 插槽完全接管单项内容,插槽仍可取得标准化后的全局索引和分组数据:

vue
<template>
  <xtf-list :groups="groups">
    <template #header>
      <text>最近动态</text>
    </template>
    <template #groupHeader="{ group }">
      <text>{{ group.title }}({{ group.items.length }} 条)</text>
    </template>
    <template #item="{ item, index }">
      <view style="padding: 24rpx; border-bottom: 1rpx solid #eee" @tap="openItem(item, index)">
        <text>{{ index + 1 }}. {{ item.title }}</text>
      </view>
    </template>
  </xtf-list>
</template>

<script>
export default {
  data() {
    return {
      groups: [{ title: '今天', items: [{ title: '商品已入库' }, { title: '退款待处理' }] }]
    }
  },
  methods: {
    openItem(item, index) {
      console.log('自定义项点击:', item.title, index)
    }
  }
}
</script>

全部属性

| 属性 | 类型 | 默认值 | 作用描述 | 适用范围 | | --- | --- | --- | --- | | items | Array<ListItem> | [] | 扁平列表数据;当 groups 为空时使用 | 普通列表 | | groups | Array<ListGroup> | [] | 分组列表数据;非空时优先于 items | 消息、设置分组 | | sectionTitle | String | '' | 列表总标题 | 需要默认头部时 | | sectionDesc | String | '' | 列表总描述 | 标题补充说明 | | theme | String | 'primary' | 未单独设置主题的项所使用的主题色 | 统一单元格主题 | | itemVariant | String | 'surface' | 未单独设置变体的项所使用的 xtf-cell 变体 | 统一单元格外观 | | grouped | Boolean | false | 是否给列表主体使用分组卡片外观 | 分组或卡片式列表 | | divider | Boolean | true | 默认是否显示项间分割线;单项 divider 可覆盖 | 普通列表 | | dividerInset | String \| Number | 88 | 默认分割线左侧缩进,数字按 rpx 处理 | 图标对齐分割线 | | actionWidth | String \| Number | 112 | 每个侧滑操作按钮宽度,数字按 rpx 处理 | 侧滑操作 | | swipeOpenThreshold | Number | 0.42 | 左滑距离达到操作区总宽度该比例时展开 | 调整侧滑灵敏度 | | loadMore | String | '' | 底部状态:loading / finished / error / more;为空不显示 | 手动分页加载 | | loadMoreTexts | Object | {} | 覆盖底部文案,支持 loadingfinishederrormore | 自定义分页文案 | | customClass | String | '' | 根节点自定义类名 | 样式覆盖 | | customStyle | String \| Object | '' | 根节点自定义样式 | 动态样式覆盖 |

groups 数组每项支持的字段

字段类型默认值说明
keyString | Number自动生成分组唯一标识
titleString''分组标题
descString''分组描述
itemsArray<ListItem>[]该分组下的列表项

items 数组每项常用字段

字段类型默认值说明
idString | Number自动生成项唯一标识
title / eyebrow / descString''标题、眉题和描述,透传给 xtf-cell
value / extra / noteString''右侧主值、附加值和说明,透传给 xtf-cell
icon / thumbString''图标或缩略图,透传给 xtf-cell
theme / variantString继承组件单项主题和变体
badge / badgeTextBoolean | String / String-徽标配置,透传给 xtf-cell
arrow / rightIconBoolean / String-右侧箭头或图标
switchable / checkedBoolean-显示开关及其状态
clickable / disabledBooleantrue / false是否可点击、是否禁用
divider / insetBoolean / String | Number继承组件覆盖分割线显示和缩进
url / openTypeString-透传给 xtf-cell 的跳转地址和打开方式
swipeActionsArray<{ text: String, color?: String }>[]左滑后显示的操作按钮
className / styleString / String | Object''单项 xtf-cell 的自定义类名和样式

事件

事件名称触发时机回调参数参数说明
click点击可点击列表项时触发(payload: { item: ListItem, index: Number })item-click 同时触发;index 为跨分组的全局索引
item-click点击可点击列表项时触发(payload: { item: ListItem, index: Number })项数据和全局索引
swipe-action点击展开后的侧滑操作按钮时触发(payload: { action: Object, item: ListItem, index: Number })action 为对应的 swipeActions
switch-change子项内置开关变化时触发(payload: { checked: Boolean, item: ListItem, index: Number })新开关值、项数据和全局索引
long-press长按列表行时触发(payload: { item: ListItem, index: Number })项数据和全局索引
load-moreloadMoremore 且点击底部时触发()由外部更新 loadMore 和数据
retry-load-moreloadMoreerror 且点击底部时触发()由外部重新发起加载

事件使用示例

vue
<template>
  <xtf-list
    :items="items"
    :load-more="loadStatus"
    @click="handleClick"
    @item-click="handleItemClick"
    @swipe-action="handleAction"
    @switch-change="handleSwitch"
    @long-press="handleLongPress"
    @load-more="handleLoad"
    @retry-load-more="handleLoad"
  />
</template>

<script>
export default {
  data() {
    return {
      loadStatus: 'more',
      items: [
        { title: '自动接单', switchable: true, checked: true, swipeActions: [{ text: '删除' }] }
      ]
    }
  },
  methods: {
    handleClick(payload) {
      console.log('click:', payload.index)
    },
    handleItemClick(payload) {
      console.log('item-click:', payload.item.title)
    },
    handleAction(payload) {
      uni.showToast({ title: payload.action.text, icon: 'none' })
    },
    handleSwitch(payload) {
      payload.item.checked = payload.checked
      console.log('switch-change:', payload.checked)
    },
    handleLongPress(payload) {
      console.log('long-press:', payload.item.title)
    },
    handleLoad() {
      this.loadStatus = 'finished'
      console.log('加载完成')
    }
  }
}
</script>

方法

1. openSwipeRow(index, item) — 展开指定项的侧滑操作区

需通过 ref 调用;item 应为对应的原始项数据,且必须含有 swipeActions

参数类型默认值说明
indexNumber-项的全局索引
itemListItem-要展开的项

返回值void

使用示例:

vue
<template><xtf-list ref="list" :items="items" /></template>
<script>
export default {
  data() {
    return { items: [{ title: '订单 #A1029', swipeActions: [{ text: '删除' }] }] }
  },
  mounted() {
    this.$refs.list.openSwipeRow(0, this.items[0])
  }
}
</script>

2. closeSwipeRow(index) — 收起指定项的侧滑操作区

参数类型默认值说明
indexNumber-要收起的全局索引

返回值void

使用示例: this.$refs.list.closeSwipeRow(0)


插槽

插槽名称作用域参数说明
header-覆盖列表默认头部
groupHeader{ group, groupIndex }覆盖每个分组的默认头部
item{ item, index, group, groupIndex }覆盖完整列表项内容
right{ item, index, group, groupIndex }在默认 xtf-cellright 插槽中追加右侧内容
load-more-覆盖底部加载状态内容

主题说明

  • 分组卡片使用 var(--xtf-card-bg)var(--xtf-card-border)var(--xtf-shadow-card)
  • 长按背景使用 var(--xtf-list-pressed-bg),加载指示器使用 var(--xtf-list-spinner-border)
  • 侧滑操作未设置 color 时使用 var(--xtf-color-danger),加载旋转边框使用 var(--xtf-color-primary)

如需全局调整主题,请在 xtf-config-provider 或主题配置中覆盖上述 CSS 变量。

MIT Licensed