# MatchTeamInfoList Team Info List
A list component for displaying team information with scroll-to-load-more functionality and empty state handling.
# Import
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
# Code Examples
# Basic Usage
<template>
<PressMatchTeamInfoList
:team-list="teamList"
:loading="loading"
:finished="finished"
@load-more="loadMore"
@apply="handleApply"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
const teamList = ref([]);
const loading = ref(false);
const finished = ref(false);
const currentPage = ref(0);
const pageSize = 10;
const loadMore = () => {
if (loading.value || finished.value) return;
loading.value = true;
// Simulate async data loading
setTimeout(() => {
const newData = generateTeamData(currentPage.value, pageSize);
if (newData.length > 0) {
teamList.value = [...teamList.value, ...newData];
currentPage.value += 1;
} else {
finished.value = true;
}
loading.value = false;
}, 1000);
};
const handleApply = (team, index) => {
console.log('Apply to join team:', team, index);
};
// Generate mock data
const generateTeamData = (page, size) => {
const data = [];
const start = page * size;
const end = start + size;
for (let i = start; i < end && i < 50; i++) {
data.push({
id: `team-${i}`,
name: `Team ${i + 1}`,
logo: `https://example.com/logo${i}.png`,
avatars: [
`https://example.com/avatar${i}-1.png`,
`https://example.com/avatar${i}-2.png`,
],
currentMembers: Math.floor(Math.random() * 5) + 1,
maxMembers: 5,
tagItems: [
{ text: 'Popular', type: 'primary' },
],
});
}
return data;
};
</script>
# Simple Mode
Hide member avatar list and action button.
<template>
<PressMatchTeamInfoList
:team-list="teamList"
:loading="loading"
:finished="finished"
item-type="simple"
@load-more="loadMore"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
const teamList = ref([
{
id: '1',
name: 'Honor of Kings Team',
logo: 'https://example.com/logo.png',
currentMembers: 3,
maxMembers: 5,
tagItems: [
{ text: 'Popular', type: 'primary' },
],
},
]);
const loading = ref(false);
const finished = ref(false);
const loadMore = () => {
console.log('Load more');
};
</script>
# Custom Empty State
<template>
<PressMatchTeamInfoList
:team-list="teamList"
:loading="loading"
:finished="finished"
empty-text="No team information available"
finish-text="All teams loaded"
@load-more="loadMore"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
const teamList = ref([]);
const loading = ref(false);
const finished = ref(false);
const loadMore = () => {
console.log('Load more');
};
</script>
# Custom Tags
You can set tags for each team individually or set default tags for all teams.
<template>
<PressMatchTeamInfoList
:team-list="teamList"
:tag-items="defaultTags"
:loading="loading"
:finished="finished"
@load-more="loadMore"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
const defaultTags = ref([
{ text: 'Recommended', type: 'primary' },
]);
const teamList = ref([
{
id: '1',
name: 'Honor of Kings Team',
logo: 'https://example.com/logo.png',
avatars: ['https://example.com/avatar1.png'],
currentMembers: 3,
maxMembers: 5,
// Individual tags override default tags
tagItems: [
{ text: 'Popular', type: 'primary' },
{ text: '3', type: 'quantity' },
],
},
{
id: '2',
name: 'PUBG Team',
logo: 'https://example.com/logo2.png',
avatars: ['https://example.com/avatar2.png'],
currentMembers: 2,
maxMembers: 5,
// Uses default tags if not set
},
]);
const loading = ref(false);
const finished = ref(false);
const loadMore = () => {
console.log('Load more');
};
</script>
# API
# Props
| Attribute | Description | Type | Default |
|---|---|---|---|
| team-list | Team list data | TeamInfo[] | [] |
| tag-items | Default tag list | TagItem[] | [] |
| item-type | List item display type | 'with-avatars' | 'simple' | 'with-avatars' |
| action-text | Action button text | string | '申请加入' |
| custom-class | Custom CSS class name | string | '' |
| empty-text | Empty state text | string | '暂无队伍信息' |
| image | Empty state image | string | - |
| finish-text | Finish loading text | string | '没有更多了' |
| loading | Whether data is loading | boolean | false |
| finished | Whether all data is loaded | boolean | false |
# TeamInfo Data Structure
interface TeamInfo {
id: string;
name: string;
logo: string;
avatars?: string[];
currentMembers: number;
maxMembers: number;
tagItems?: TagItem[];
}
| Property | Description | Type | Required |
|---|---|---|---|
| id | Team ID | string | Yes |
| name | Team name | string | Yes |
| logo | Team logo URL | string | Yes |
| avatars | Member avatar list | string[] | No |
| currentMembers | Current member count | number | Yes |
| maxMembers | Maximum member count | number | Yes |
| tagItems | Team tag list, overrides default tags | TagItem[] | No |
# TagItem Data Structure
interface TagItem {
text: string;
type?: 'default' | 'quantity';
}
| Property | Description | Type | Default |
|---|---|---|---|
| text | Tag text | string | - |
| type | Tag type, quantity type shows user icon | 'default' | 'quantity' | 'default' |
# Events
| Event | Description | Callback Parameters |
|---|---|---|
| load-more | Triggered when scrolled to bottom | - |
| apply | Triggered when apply button is clicked | team: TeamInfo, index: number |
# Theme Customization
# CSS Variables
The component provides the following CSS variables for custom styling.
# Spacing System
| Name | Default | Description |
|---|---|---|
| --til-list-gap | 0 | List item gap |
| --til-list-item-border-offset | $spacing-lg | List item border offset |
# Color System
| Name | Default | Description |
|---|---|---|
| --til-bg-color | transparent | List background color |
| --til-list-item-border-color | $color-divider-light | List item border color |
# Custom Style Example
<template>
<PressMatchTeamInfoList
:team-list="teamList"
class="custom-team-list"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
const teamList = ref([
{
id: '1',
name: 'Honor of Kings Team',
logo: 'https://example.com/logo.png',
avatars: ['https://example.com/avatar1.png'],
currentMembers: 3,
maxMembers: 5,
},
]);
</script>
<style scoped lang="scss">
.custom-team-list {
--til-bg-color: #f5f5f5;
--til-list-gap: 16px;
--til-list-item-border-color: #e0e0e0;
}
</style>
# Notes
Component Dependencies:
- Uses
PressMatchTeamInfoItemcomponent frompress-next - Uses
PressListandPressEmptycomponents frompress-ui - Ensure all dependencies are properly installed
- Uses
Data Loading:
- The component doesn't handle data fetching logic itself
- Implement data loading in the parent component through the
load-moreevent - Recommend paginated loading for large datasets to avoid rendering too much content at once
State Management:
- Properly manage
loadingandfinishedstates in the parent component - Set
loading: truewhen loading starts,loading: falsewhen complete - Set
finished: truewhen no more data is available
- Properly manage
Tag Priority:
tagItemsin team data overrides the component'stag-itemsprop- If team data doesn't have
tagItems, default tags are used
Display Modes:
with-avatarsmode: Shows member avatar list and action buttonsimplemode: Hides avatar list and action button
# FAQ
# How to implement pull-to-refresh?
Use with press-ui's pull-refresh component:
<template>
<PressPullRefresh
v-model="refreshing"
@refresh="onRefresh"
>
<PressMatchTeamInfoList
:team-list="teamList"
:loading="loading"
:finished="finished"
@load-more="loadMore"
/>
</PressPullRefresh>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchTeamInfoList from 'press-next/press-match-team-info-list/press-match-team-info-list.vue';
import PressPullRefresh from 'press-ui/press-pull-refresh/press-pull-refresh.vue';
const teamList = ref([]);
const loading = ref(false);
const finished = ref(false);
const refreshing = ref(false);
const onRefresh = async () => {
// Reset state
teamList.value = [];
finished.value = false;
// Reload data
await loadMore();
refreshing.value = false;
};
const loadMore = async () => {
loading.value = true;
// Data loading logic
loading.value = false;
};
</script>
# How to customize team item styles?
The component uses PressMatchTeamInfoItem internally to render each team item. Customize using CSS variables:
<template>
<PressMatchTeamInfoList
:team-list="teamList"
class="custom-list"
/>
</template>
<style scoped lang="scss">
.custom-list {
// Customize list styles
--til-list-gap: 16px;
// Customize team item styles
--pmtii-container-bg: #f5f5f5;
--pmtii-name-text-color: #1890ff;
}
</style>
# LoadingPlus state display issues?
Check your loading and finished state management logic:
<script setup lang="ts">
const loading = ref(false);
const finished = ref(false);
const loadMore = async () => {
// Prevent duplicate loading
if (loading.value || finished.value) return;
loading.value = true;
try {
const newData = await fetchTeamData();
if (newData.length > 0) {
teamList.value = [...teamList.value, ...newData];
} else {
// No more data
finished.value = true;
}
} catch (error) {
console.error('Loading failed:', error);
} finally {
// Ensure loading state is reset
loading.value = false;
}
};
</script>
# How to handle apply logic?
Listen to the apply event and handle the logic in the callback:
<template>
<PressMatchTeamInfoList
:team-list="teamList"
@apply="handleApply"
/>
</template>
<script setup lang="ts">
const handleApply = async (team, index) => {
try {
// Call apply API
await applyToJoinTeam(team.id);
console.log('Application successful');
// Update list state
teamList.value[index].isApplied = true;
} catch (error) {
console.error('Application failed:', error);
}
};
</script>