# 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>