# MatchRoundSetList 轮次设置列表
轮次设置列表组件,用于显示比赛的多个轮次设置信息,包含表头和轮次项列表。
# 引入
import PressMatchRoundSetList from 'press-next/press-match-round-set-list/press-match-round-set-list';
# 代码演示
# 基础用法
<PressMatchRoundSetList
:list="roundSetList"
@item-click="onItemClick"
@action-click="onActionClick"
/>
# 自定义样式
<PressMatchRoundSetList
custom-class="custom-round-set-list"
:list="roundSetList"
@item-click="onItemClick"
@action-click="onActionClick"
/>
# 自定义列配置
<PressMatchRoundSetList
:list="roundSetList"
:columns="customColumns"
@item-click="onItemClick"
@action-click="onActionClick"
/>
// 自定义列配置
const customColumns = [
{ key: 'rounds', title: '轮次', width: '1.5rem', align: 'left' },
{ key: 'settings', title: '开赛设置', width: '2.5rem', align: 'center' },
{ key: 'ways', title: '决胜方式', width: '1.8rem', align: 'center' },
{ key: 'operate', title: '操作', width: '2rem', align: 'center' }
];
# API
# Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| custom-class | 自定义样式类名 | string | '' |
| list | 轮次设置数据列表 | RoundSetItemData[] | [] |
| columns | 表格列配置 | Column[] | getTableColumns() |
# Column 接口
interface Column {
key: string;
title: string;
width?: string;
minWidth?: string;
align?: 'left' | 'center' | 'right';
sortable?: boolean;
}
# RoundSetItemData 数据结构
interface RoundSetItemData {
roundName: string; // 轮次名称
timeText: string; // 开赛时间文本
formatText: string; // 决胜方式文本
actionText: string; // 操作文本
selected?: boolean; // 是否选中
disabled?: boolean; // 是否禁用
editable?: boolean; // 是否可编辑
showTimeIcon?: boolean; // 是否显示时间图标
showFormatIcon?: boolean; // 是否显示决胜方式图标
hasStarted?: boolean; // 是否已开始
canSetTime?: boolean; // 是否可设置时间
canSetBo?: boolean; // 是否可设置决胜方式
bo_type?: number; // 决胜方式类型 (1: 一局胜负, 3: 三局两胜, 5: 五局三胜, 7: 七局四胜)
}
# Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| item-click | 点击轮次项时触发 | (item: RoundSetItemData, index: number) |
| action-click | 点击操作按钮时触发 | (item: RoundSetItemData, index: number) |
| time-click | 点击时间设置时触发 | (item: RoundSetItemData, index: number) |
| format-click | 点击决胜方式设置时触发 | (item: RoundSetItemData, index: number) |
| set-round-bo | 设置轮次决胜方式时触发 | (data: { currentRound: RoundSetItemData; value: number }) |
| set-round-time | 设置轮次时间时触发 | (data: { currentRound: RoundSetItemData; value: any }) |
| start-all-round | 开始整轮比赛时触发 | (data: { currentRound: RoundSetItemData }) |
| sort | 表头排序时触发 | (data: { key: string; order: 'asc' \| 'desc' \| null }) |
# 样式定制
# CSS 变量
组件提供了丰富的 CSS 变量用于样式定制,所有变量都使用 --mrsl- 前缀:
/* 定位属性 */
--mrsl-container-position: relative; /* 容器定位方式 */
--mrsl-header-position: relative; /* 表头定位方式 */
--mrsl-content-position: relative; /* 内容区域定位方式 */
/* 盒模型属性 */
--mrsl-container-width: 100%; /* 容器宽度 */
--mrsl-container-height: auto; /* 容器高度 */
--mrsl-header-width: 100%; /* 表头宽度 */
--mrsl-header-height: .7rem; /* 表头高度 */
--mrsl-header-padding: .14rem .22rem; /* 表头内边距 */
--mrsl-content-width: 100%; /* 内容区域宽度 */
--mrsl-content-height: calc(100% - .7rem); /* 内容区域高度 */
--mrsl-header-item-round-min-width: 1.2rem; /* 轮次表头项最小宽度 */
--mrsl-header-item-time-min-width: 2rem; /* 时间表头项最小宽度 */
--mrsl-header-item-format-min-width: 1.4rem; /* 决胜方式表头项最小宽度 */
--mrsl-header-item-action-min-width: 1.6rem; /* 操作表头项最小宽度 */
/* 边框属性 */
--mrsl-container-border-radius: $border-radius-none; /* 容器圆角 */
/* 背景属性 */
--mrsl-container-bg: linear-gradient(91deg, rgba(237, 239, 241, .5) 0%, rgba(252, 252, 252, .5) 100%); /* 容器背景渐变 */
--mrsl-header-bg: url(https://image-1251917893.file.myqcloud.com/general-match-components/img/match-round-set-list/table-header.png); /* 表头背景图片 */
--mrsl-header-bg-size: 100% 100%; /* 表头背景图片尺寸 */
/* 文本属性 */
--mrsl-header-item-color: $color-text-invert-light; /* 表头项文字颜色 */
--mrsl-header-item-font-size: $font-size-xs; /* 表头项字体大小 */
--mrsl-header-item-font-weight: $font-weight-regular; /* 表头项字重 */
--mrsl-header-item-time-text-align: center; /* 时间表头项文字对齐 */
--mrsl-header-item-format-text-align: center; /* 决胜方式表头项文字对齐 */
--mrsl-header-item-action-text-align: right; /* 操作表头项文字对齐 */
/* 其他属性 */
--mrsl-content-overflow-y: auto; /* 内容区域垂直滚动 */
/* 表头滚动相关 */
--mrsl-header-scroll-min-width: calc(1.48rem + 1.94rem + 1.6rem + 1.6rem); /* 表头滚动最小宽度 */
--mrsl-header-scroll-overflow-x: auto; /* 表头水平滚动 */
--mrsl-header-scrollbar-width: none; /* Firefox滚动条宽度 */
--mrsl-header-scrollbar-style: none; /* IE滚动条样式 */
--mrsl-header-webkit-scrollbar-display: none; /* Webkit滚动条显示 */
/* 表头单元格相关 */
--mrsl-header-cell-flex-shrink: 0; /* 表头单元格收缩 */
# 主题定制示例
/* 深色主题 */
.dark-theme {
--mrsl-container-bg: linear-gradient(91deg, rgba(30, 30, 30, .8) 0%, rgba(50, 50, 50, .8) 100%);
--mrsl-header-item-color: #ffffff;
}
/* 紧凑布局 */
.compact-layout {
--mrsl-header-height: .6rem;
--mrsl-header-padding: .12rem .18rem;
--mrsl-header-item-font-size: $font-size-xxs;
}
/* 自定义尺寸 */
.custom-size {
--mrsl-header-item-round-min-width: 1.2rem;
--mrsl-header-item-time-min-width: 1.4rem;
--mrsl-header-item-format-min-width: 1.3rem;
--mrsl-header-item-action-min-width: 1.3rem;
}
# 设计系统集成
组件完全集成了设计系统,使用语义化变量:
- 颜色系统: 引用
$color-text-invert-light等语义变量 - 字体系统: 使用
$font-size-xs、$font-weight-regular标准字体变量 - 边框系统: 使用
$border-radius-none标准圆角变量
# 架构设计
组件采用CSS变量传递的方式与子组件通信,避免使用 :deep() 样式穿透:
// 父组件通过CSS变量传递样式给表头组件
&__header {
--pmth-header-overflow-x: auto;
--pmth-header-min-width: calc(1.48rem + 1.94rem + 1.6rem + 1.6rem);
--pmth-header-scrollbar-width: none;
--pmth-header-cell-round-min-width: 1.48rem;
--pmth-header-cell-time-min-width: 1.94rem;
// 更多变量...
}
// 父组件通过CSS变量传递样式给轮次项组件,确保宽度同步
&__content {
--mrsi-round-min-width: 1.48rem;
--mrsi-time-min-width: 1.94rem;
--mrsi-format-min-width: 1.6rem;
--mrsi-action-min-width: 1.6rem;
--mrsi-container-scrollbar-width: none;
// 更多变量...
}
# 宽度同步机制
为了确保表头单元格和内容项的宽度完全同步,组件采用了双重同步策略:
1. CSS 变量同步(原有方式)
- 统一变量源: 所有宽度都来自
$mrsl-header-item-*-min-width变量 - 双向传递: 同时传递给表头组件和轮次项组件
- 动态计算: 容器最小宽度通过变量动态计算
// 轮次项组件中的动态计算
min-width: calc(#{$mrsi-round-min-width} + #{$mrsi-time-min-width} + #{$mrsi-format-min-width} + #{$mrsi-action-min-width});
2. 列配置同步(新增方式)
- 统一配置源: 表头和内容项使用相同的
tableColumns配置 - 直接传递: 将表头的列配置直接传递给轮次项组件
- 优先级更高: 当同时存在时,列配置优先于 CSS 变量
// 表格列配置 - 与 press-match-table-header demo-data 保持一致
const tableColumns = [
{ key: 'rounds', title: '轮次', width: '1.2rem', align: 'left' },
{ key: 'settings', title: '开赛设置', width: '2rem', align: 'center' },
{ key: 'ways', title: '决胜方式', width: '1.4rem', align: 'center' },
{ key: 'operate', title: '操作', width: '1.6rem', align: 'center' }
];
这种设计的优势:
- ✅ 样式封装性: 不破坏组件的样式隔离
- ✅ 宽度同步: 确保表头和内容项宽度完全一致
- ✅ 兼容性: 不需要修改现有子组件
- ✅ 可维护性: 避免样式穿透带来的维护问题
- ✅ 性能优化: 减少样式计算开销
- ✅ 扩展性: 便于后续功能扩展
- ✅ 灵活配置: 支持运行时动态调整列宽度
# 使用示例
<template>
<div class="demo-container">
<PressMatchRoundSetList
:list="roundSetList"
@item-click="onItemClick"
@action-click="onActionClick"
@time-click="onTimeClick"
@format-click="onFormatClick"
@set-round-bo="onSetRoundBo"
@set-round-time="onSetRoundTime"
@start-all-round="onStartAllRound"
@sort="onSort"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PressMatchRoundSetList from 'press-next/press-match-round-set-list/press-match-round-set-list';
const roundSetList = ref([
{
roundName: '32进16',
timeText: '3月18日 12:00',
formatText: '一局胜负',
actionText: '整轮开赛',
editable: true,
showTimeIcon: true,
showFormatIcon: true,
hasStarted: false,
canSetTime: true,
canSetBo: true,
bo_type: 1,
},
{
roundName: '16进8',
timeText: '3月19日 14:00',
formatText: '三局两胜',
actionText: '整轮开赛',
editable: true,
showTimeIcon: true,
showFormatIcon: true,
hasStarted: false,
canSetTime: true,
canSetBo: true,
bo_type: 3,
},
// 更多数据...
]);
const onItemClick = (item, index) => {
console.log('点击轮次:', item.roundName, index);
};
const onActionClick = (item, index) => {
console.log('点击操作:', item.actionText, index);
};
const onTimeClick = (item, index) => {
console.log('点击时间设置:', item.timeText, index);
};
const onFormatClick = (item, index) => {
console.log('点击决胜方式设置:', item.formatText, index);
};
const onSetRoundBo = (data) => {
console.log('设置决胜方式:', data.currentRound.roundName, data.value);
// 更新数据
data.currentRound.bo_type = data.value;
};
const onSetRoundTime = (data) => {
console.log('设置时间:', data.currentRound.roundName, data.value);
// 更新数据
data.currentRound.timeText = formatTime(data.value);
};
const onStartAllRound = (data) => {
console.log('开始整轮:', data.currentRound.roundName);
// 更新状态
data.currentRound.hasStarted = true;
};
const onSort = (data) => {
console.log('排序:', data.key, data.order);
// 处理排序逻辑
};
const formatTime = (timestamp) => {
const date = new Date(timestamp);
return `${date.getMonth() + 1}月${date.getDate()}日 ${date.getHours()}:${date.getMinutes().toString().padStart(2, '0')}`;
};
</script>