# MatchChangeScorePopup 改分弹窗
比赛改分弹窗组件,用于裁判或管理员修改比赛分数,支持双队比分调整和双方判负功能。
# 特性
- 🎯 分数调整 - 支持增减双方队伍比分,范围0-999
- 👥 双队显示 - 清晰展示两支队伍信息和当前比分
- ⚖️ 双方判负 - 一键设置双方判负功能
- 🎨 自定义样式 - 丰富的CSS变量支持主题定制
- 🔧 插槽支持 - 支持自定义确认按钮和双败按钮插槽
- 🔒 数据验证 - 自动限制分数范围,防止异常输入
- ⚡ 轻量高效 - 优化的代码结构,性能出色
# 适用场景
- 电竞比赛分数修正
- 体育赛事比分调整
- 在线游戏对战结果修改
- 比赛管理系统
# 引入
import PressMatchChangeScorePopup from 'press-next/press-match-change-score-popup/press-match-change-score-popup';
# 代码演示
# 基础用法
<template>
<div class="demo-wrap">
<h3>基础用法</h3>
<PressButton @click="showBasicPopup = true">
显示基础改判比分弹窗
</PressButton>
<PressMatchChangeScorePopup
:show="showBasicPopup"
:z-index="componentProps.zIndex"
:left-team="componentProps.leftTeam"
:right-team="componentProps.rightTeam"
:initial-left-score="componentProps.initialLeftScore"
:initial-right-score="componentProps.initialRightScore"
:custom-class="componentProps.customClass"
@close="onBasicClose"
@confirm="onBasicConfirm"
@both-lose="onBasicBothLose"
/>
</div>
</template>
<script setup>
import { ref } from 'vue';
import PressButton from 'press-ui/press-button/press-button.vue';
import PressMatchChangeScorePopup from 'press-next/press-match-change-score-popup/press-match-change-score-popup.vue';
import { getMockData } from './demo-data';
// 使用模拟数据
const componentProps = getMockData();
// 弹窗显示状态
const showBasicPopup = ref(false);
// 基础用法事件处理
const onBasicConfirm = (leftScore, rightScore) => {
console.log('基础用法 - 确认改判:', { leftScore, rightScore });
showBasicPopup.value = false;
};
const onBasicClose = () => {
console.log('基础用法 - 关闭弹窗');
showBasicPopup.value = false;
};
const onBasicBothLose = (leftScore, rightScore) => {
console.log('基础用法 - 双方判负:', { leftScore, rightScore });
showBasicPopup.value = false;
};
</script>
# 自定义插槽用法
<template>
<div class="demo-wrap">
<h3>自定义插槽用法</h3>
<PressButton @click="showSlotPopup = true">
显示自定义插槽弹窗
</PressButton>
<PressMatchChangeScorePopup
:show="showSlotPopup"
:z-index="componentProps.zIndex"
:left-team="componentProps.leftTeam"
:right-team="componentProps.rightTeam"
:initial-left-score="componentProps.initialLeftScore"
:initial-right-score="componentProps.initialRightScore"
@close="onSlotClose"
@confirm="onSlotConfirm"
@both-lose="onSlotBothLose"
>
<!-- 自定义确认按钮 -->
<template #confirm-btn>
<PressButton
:class="`${prefix}__custom-confirm`"
size="small"
type="primary"
@click="onSlotConfirm"
>
自定义确认
</PressButton>
</template>
<!-- 自定义双方判负按钮 -->
<template #bothLoseBtn>
<div :class="`${prefix}__custom-both-lose`" @click="onSlotBothLose">
<div class="pmg-iconfont pmg-icon-warning" />
<div :class="`${prefix}__custom-both-lose-text`">
自定义双败
</div>
</div>
</template>
</PressMatchChangeScorePopup>
</div>
</template>
<script setup>
import { ref } from 'vue';
import PressButton from 'press-ui/press-button/press-button.vue';
import PressMatchChangeScorePopup from 'src/packages/press-match-change-score-popup/press-match-change-score-popup.vue';
import { getMockData } from 'src/packages/press-match-change-score-popup/demo-data';
const prefix = 'pm-change-score-popup';
// 使用模拟数据
const componentProps = getMockData();
// 弹窗显示状态
const showSlotPopup = ref(false);
// 自定义插槽事件处理
const onSlotConfirm = (leftScore, rightScore) => {
if (leftScore !== undefined && rightScore !== undefined) {
console.log('插槽用法 - 确认改判:', { leftScore, rightScore });
} else {
console.log('插槽用法 - 自定义确认按钮点击');
}
showSlotPopup.value = false;
};
const onSlotClose = () => {
console.log('插槽用法 - 关闭弹窗');
showSlotPopup.value = false;
};
const onSlotBothLose = (leftScore, rightScore) => {
if (leftScore !== undefined && rightScore !== undefined) {
console.log('插槽用法 - 双方判负:', { leftScore, rightScore });
} else {
console.log('插槽用法 - 自定义双败按钮点击');
}
showSlotPopup.value = false;
};
</script>
<style scoped lang="scss">
.pm-change-score-popup {
&__custom-confirm {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border: none;
}
&__custom-both-lose {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
padding: 8px 16px;
background: rgba(255, 107, 107, 0.1);
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
background: rgba(255, 107, 107, 0.2);
}
.pmg-iconfont {
color: #ff6b6b;
font-size: 16px;
}
}
&__custom-both-lose-text {
color: #ff6b6b;
font-size: 14px;
font-weight: 500;
}
}
</style>
# 自定义样式
<template>
<PressMatchChangeScorePopup
:show="showPopup"
:left-team="leftTeam"
:right-team="rightTeam"
:initial-left-score="1"
:initial-right-score="2"
custom-class="custom-score-popup"
@close="handleClose"
@confirm="handleConfirm"
/>
</template>
<script setup>
import { ref } from 'vue';
const showPopup = ref(true);
const leftTeam = ref({ name: '红队', avatar: '' });
const rightTeam = ref({ name: '蓝队', avatar: '' });
const handleClose = () => {
showPopup.value = false;
};
const handleConfirm = (leftScore, rightScore) => {
console.log('比分确认:', leftScore, rightScore);
};
</script>
<style>
.custom-score-popup {
--csp-popup-bg: #f8f9fa;
--csp-score-btn-bg: #007bff;
--csp-team-info-name-color: #333;
}
</style>
# API
# Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| custom-class | 自定义样式类 | string | '' |
| z-index | 弹窗层级 | number | 100 |
| title | 弹窗标题 | string | '改判比分' |
| show | 是否显示弹窗 | boolean | false |
| left-team | 左队信息 | TeamInfo | { name: '战队名称A' } |
| right-team | 右队信息 | TeamInfo | { name: '战队名称A' } |
| initial-left-score | 初始左队比分 | number | 0 |
| initial-right-score | 初始右队比分 | number | 5 |
| slot-confirm-btn | 是否使用确认按钮插槽 | boolean | false |
| slot-both-lose-btn | 是否使用双败按钮插槽 | boolean | false |
# TeamInfo 数据结构
interface TeamInfo {
name: string; // 队伍名称
avatar?: string; // 队伍头像URL,可选
}
# Events
| 事件名 | 说明 | 参数 |
|---|---|---|
| close | 关闭弹窗时触发 | - |
| confirm | 确认改分时触发 | leftScore: number, rightScore: number |
| both-lose | 双方判负时触发 | leftScore: number, rightScore: number |
# Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
| confirm-btn | 自定义确认按钮 | - |
| bothLoseBtn | 自定义双方判负按钮 | - |
插槽使用说明:
confirm-btn插槽用于替换默认的确认按钮,需要自行处理点击事件bothLoseBtn插槽用于替换默认的双方判负按钮,需要自行处理点击事件- 插槽内容会完全替换默认按钮,请确保提供合适的交互元素
# 注意事项
# 使用建议
- 分数范围:组件自动限制分数范围在0-999之间,超出范围会自动调整
- 队伍头像:建议为队伍头像设置默认占位图,避免加载失败时显示空白
- 弹窗层级:在复杂页面中使用时,注意调整
z-index避免层级冲突 - 事件处理:确保正确处理
confirm和both-lose事件,更新业务数据 - 插槽使用:使用自定义插槽时,插槽内容会完全替换默认按钮,请确保自行处理点击事件
- 响应式适配:在小屏幕设备上,建议适当调整相关尺寸变量
# 性能优化
- 使用
v-show控制弹窗显示,避免频繁创建销毁 - 合理使用
computed优化数据计算 - 避免在弹窗内进行复杂的数据处理
# 兼容性
- 支持 Vue 3.0+
- 兼容现代浏览器(Chrome 60+, Firefox 60+, Safari 12+)
- 支持微信小程序、支付宝小程序等平台
# 主题定制
# 样式变量
组件提供了下列 CSS 变量,可用于自定义样式,使用方法请参考 ConfigProvider 组件。
# 尺寸属性 (Width/Height)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-head-confirm-width | 1.4rem | 确认按钮宽度 |
| --csp-head-confirm-height | .56rem | 确认按钮高度 |
| --csp-content-team-min-height | 1.12rem | 队伍内容最小高度 |
| --csp-team-info-avatar-size | .8rem | 队伍头像尺寸 |
| --csp-content-team-score-width | 2rem | 比分区域宽度 |
| --csp-content-team-score-height | .44rem | 比分区域高度 |
| --csp-score-number-width | 1.14rem | 分数数字宽度 |
| --csp-score-number-height | .44rem | 分数数字高度 |
| --csp-score-btn-size | .44rem | 分数按钮尺寸 |
| --csp-score-btn-sub-width | .272rem | 减分按钮宽度 |
| --csp-score-btn-sub-height | .04rem | 减分按钮高度 |
| --csp-warning-height | .96rem | 警告区域高度 |
# 间距属性 (Margin/Padding/Gap)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-popup-head-padding-top | $spacing-md | 弹窗头部上内边距 |
| --csp-popup-head-margin-bottom | $spacing-lg | 弹窗头部下外边距 |
| --csp-content-team-padding | .32rem 0 .16rem | 队伍内容内边距 |
| --csp-popup-content-margin-bottom | .4rem | 弹窗内容下外边距 |
| --csp-team-info-avatar-margin-right | $spacing-sm | 队伍头像右外边距 |
| --csp-content-team-score-margin | auto 0 | 比分区域外边距 |
| --csp-content-team-score-gap | 0 | 比分区域间距 |
| --csp-warning-padding-bottom | .28rem | 警告区域下内边距 |
| --csp-warning-gap | $spacing-xs | 警告区域间距 |
# 颜色属性 (Color/Background)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-popup-bg | $color-surface-default | 弹窗背景色 |
| --csp-score-btn-bg | $color-icon-dark | 分数按钮背景色 |
| --csp-score-btn-disabled-bg | $color-surface-secondary | 禁用按钮背景色 |
| --csp-score-btn-sub-bg | $color-text-primary | 减分按钮背景色 |
| --csp-score-number-bg | rgba(247, 249, 250, 1) | 分数数字背景色 |
| --csp-score-btn-color | $color-text-invert-light | 分数按钮文字颜色 |
| --csp-score-number-color | $color-text-primary | 分数数字颜色 |
| --csp-team-info-name-color | $color-text-primary | 队伍名称颜色 |
| --csp-warning-icon-color | $color-icon-dark | 警告图标颜色 |
| --csp-warning-text-color | $color-text-primary | 警告文字颜色 |
# 字体属性 (Font)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-head-confirm-font-size | $font-size-sm | 确认按钮字体大小 |
| --csp-team-info-name-font-size | $font-size-lg | 队伍名称字体大小 |
| --csp-score-number-font-size | $font-size-md | 分数数字字体大小 |
| --csp-score-number-font-weight | $font-weight-bold | 分数数字字体粗细 |
| --csp-score-btn-icon-font-size | .38rem | 分数按钮图标大小 |
| --csp-warning-text-font-size | .32rem | 警告文字字体大小 |
| --csp-warning-icon-font-size | $font-size-xl | 警告图标字体大小 |
# 边框属性 (Border/Border-Radius)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-content-team-border-bottom | .02rem solid #eaeff2 | 队伍内容下边框 |
| --csp-team-info-avatar-border-radius | $border-radius-circle | 队伍头像圆角 |
| --csp-score-btn-sub-border-radius | $border-radius-xs | 减分按钮圆角 |
# 定位属性 (Position/Top/Left/Z-Index)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-popup-position | relative | 弹窗定位 |
| --csp-popup-head-position | relative | 弹窗头部定位 |
# 布局属性 (Flex)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-team-info-flex | 1 | 队伍信息flex值 |
| --csp-score-btn-flex-shrink | 0 | 分数按钮收缩值 |
# 其他属性 (Others)
| 名称 | 默认值 | 描述 |
|---|---|---|
| --csp-team-info-avatar-object-fit | cover | 队伍头像适应方式 |