# MatchJoinTeamPopup 加入战队弹窗
用于展示战队信息并允许用户申请加入战队的弹窗组件,包含战队成员展示、参赛必读入口和加入操作。
# 引入
import PressMatchJoinTeamPopup from 'press-next/press-match-join-team-popup/press-match-join-team-popup';
# 代码演示
# 基础用法
<template>
<PressButton @click="show = true">
加入战队
</PressButton>
<PressMatchJoinTeamPopup
:show="show"
title="加入阵营并参赛"
:team-data="teamData"
button-text="申请加入"
@close="handleClose"
@confirm="handleConfirm"
@member-click="handleMemberClick"
@add-click="handleAddClick"
@read-rules-click="handleReadRulesClick"
/>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(false);
const teamData = ref({
id: 1,
teamName: '王者战队',
members: [
{
id: 1,
name: '队长小明',
avatar: 'https://example.com/avatar1.jpg',
isCaptain: true,
},
{
id: 2,
name: '队员小红',
avatar: 'https://example.com/avatar2.jpg',
isCaptain: false,
},
{
id: 3,
name: '队员小李',
avatar: 'https://example.com/avatar3.jpg',
isCaptain: false,
},
],
maxMembers: 5,
showAddButton: true,
addButtonText: '邀请队友',
});
const handleClose = () => {
show.value = false;
};
const handleConfirm = () => {
console.log('申请加入战队');
// 发送加入申请
applyToJoinTeam();
show.value = false;
};
const handleMemberClick = (member) => {
console.log('点击成员:', member);
// 查看成员详情
viewMemberProfile(member);
};
const handleAddClick = () => {
console.log('点击邀请队友');
// 打开邀请界面
openInviteDialog();
};
const handleReadRulesClick = () => {
console.log('查看参赛必读');
// 跳转到规则页面
navigateToRules();
};
// API调用函数
const applyToJoinTeam = async () => {
// 发送加入申请到服务器
};
const viewMemberProfile = (member) => {
// 查看成员详情
};
const openInviteDialog = () => {
// 打开邀请对话框
};
const navigateToRules = () => {
// 跳转到参赛规则页面
};
</script>
# 高级用法
<template>
<PressMatchJoinTeamPopup
:show="show"
title="加入精英战队"
:team-data="teamData"
button-text="立即申请"
custom-class="custom-join-team-popup"
@close="handleClose"
@confirm="handleConfirm"
@member-click="handleMemberClick"
@add-click="handleAddClick"
@read-rules-click="handleReadRulesClick"
>
<!-- 自定义底部按钮 -->
<template #foot-btn>
<div class="custom-buttons">
<PressButton
type="default"
@click="handleCancel"
>
取消
</PressButton>
<PressButton
type="primary"
@click="handleApply"
>
申请加入
</PressButton>
</div>
</template>
</PressMatchJoinTeamPopup>
</template>
<script setup>
import { ref } from 'vue';
const show = ref(false);
const teamData = ref({
id: 2,
teamName: '精英战队 Elite Squad',
members: [
{
id: 1,
name: '队长Pro',
avatar: 'https://example.com/captain.jpg',
isCaptain: true,
level: 'Diamond',
winRate: '85%',
},
{
id: 2,
name: 'Ace选手',
avatar: 'https://example.com/ace.jpg',
isCaptain: false,
level: 'Master',
winRate: '78%',
},
{
id: 3,
name: 'Support王',
avatar: 'https://example.com/support.jpg',
isCaptain: false,
level: 'Diamond',
winRate: '82%',
},
{
id: 4,
name: 'Jungle神',
avatar: 'https://example.com/jungle.jpg',
isCaptain: false,
level: 'Master',
winRate: '90%',
},
],
maxMembers: 5,
showAddButton: false, // 不显示添加按钮
requirements: {
minLevel: 'Diamond',
minWinRate: '70%',
},
});
const handleClose = () => {
console.log('弹窗关闭');
show.value = false;
};
const handleConfirm = () => {
console.log('默认确认操作');
show.value = false;
};
const handleMemberClick = (member) => {
console.log('查看成员详情:', member);
// 显示成员详细信息弹窗
showMemberDetails({
name: member.name,
level: member.level,
winRate: member.winRate,
isCaptain: member.isCaptain,
});
};
const handleAddClick = () => {
console.log('邀请新成员');
// 这个例子中不会触发,因为showAddButton为false
};
const handleReadRulesClick = () => {
console.log('查看参赛必读');
// 跳转到详细规则页面
window.open('/match/rules', '_blank');
};
const handleCancel = () => {
console.log('取消加入');
show.value = false;
};
const handleApply = async () => {
console.log('申请加入精英战队');
try {
// 检查用户是否满足加入条件
const userQualified = await checkUserQualification();
if (!userQualified) {
showMessage('您的等级或胜率不满足加入条件');
return;
}
// 发送加入申请
await submitJoinApplication(teamData.value.id);
showMessage('申请已提交,请等待队长审核');
show.value = false;
} catch (error) {
console.error('申请失败:', error);
showMessage('申请失败,请稍后重试');
}
};
// 工具函数
const showMemberDetails = (member) => {
// 显示成员详情弹窗
console.log('显示成员详情:', member);
};
const checkUserQualification = async () => {
// 检查用户资格
return true; // 示例返回
};
const submitJoinApplication = async (teamId) => {
// 提交加入申请
console.log('提交申请到团队:', teamId);
};
const showMessage = (message) => {
// 显示提示消息
console.log('提示:', message);
};
</script>
<style scoped>
.custom-buttons {
display: flex;
gap: 12px;
}
.custom-buttons .press-button {
flex: 1;
}
</style>
# 动态战队数据
<template>
<div class="demo-controls">
<PressButton @click="loadTeamData('full')">满员战队</PressButton>
<PressButton @click="loadTeamData('recruiting')">招募中</PressButton>
<PressButton @click="loadTeamData('elite')">精英战队</PressButton>
</div>
<PressMatchJoinTeamPopup
:show="show"
:title="currentTeam.title"
:team-data="currentTeam.data"
:button-text="currentTeam.buttonText"
@close="show = false"
@confirm="handleDynamicConfirm"
@member-click="handleMemberClick"
@add-click="handleAddClick"
@read-rules-click="handleReadRulesClick"
/>
</template>
<script setup>
import { ref, reactive } from 'vue';
const show = ref(false);
const currentTeam = reactive({
title: '',
data: null,
buttonText: '',
});
const teamConfigs = {
full: {
title: '战队已满员',
buttonText: '申请替补',
data: {
id: 1,
teamName: '满员战队',
members: Array.from({ length: 5 }, (_, i) => ({
id: i + 1,
name: `队员${i + 1}`,
avatar: `https://example.com/avatar${i + 1}.jpg`,
isCaptain: i === 0,
})),
maxMembers: 5,
showAddButton: false,
},
},
recruiting: {
title: '加入战队',
buttonText: '立即加入',
data: {
id: 2,
teamName: '招募战队',
members: Array.from({ length: 3 }, (_, i) => ({
id: i + 1,
name: `队员${i + 1}`,
avatar: `https://example.com/avatar${i + 1}.jpg`,
isCaptain: i === 0,
})),
maxMembers: 5,
showAddButton: true,
addButtonText: '邀请好友',
},
},
elite: {
title: '申请加入精英战队',
buttonText: '提交申请',
data: {
id: 3,
teamName: '精英战队',
members: Array.from({ length: 4 }, (_, i) => ({
id: i + 1,
name: `精英${i + 1}`,
avatar: `https://example.com/elite${i + 1}.jpg`,
isCaptain: i === 0,
level: 'Master',
})),
maxMembers: 5,
showAddButton: false,
},
},
};
const loadTeamData = (type) => {
const config = teamConfigs[type];
Object.assign(currentTeam, config);
show.value = true;
};
const handleDynamicConfirm = () => {
console.log(`${currentTeam.title}确认操作`);
show.value = false;
};
const handleMemberClick = (member) => {
console.log('点击成员:', member);
};
const handleAddClick = () => {
console.log('点击添加按钮');
};
const handleReadRulesClick = () => {
console.log('查看参赛必读');
};
</script>
# API
# Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| show | 是否显示弹窗 | boolean | false |
| title | 弹窗标题 | string | '加入阵营并参赛' |
| teamData | 战队数据 | TeamData | undefined |
| buttonText | 按钮文案 | string | '申请加入' |
| customClass | 自定义CSS类名 | string | '' |
# TeamData 数据结构
interface TeamMember {
id?: string | number;
name: string;
avatar: string;
isCaptain?: boolean;
[key: string]: any; // 支持扩展字段
}
interface TeamData {
id?: string | number;
teamName: string;
members: TeamMember[];
maxMembers?: number;
showAddButton?: boolean;
addButtonText?: string;
}
# Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| close | 弹窗关闭时触发 | - |
| confirm | 确认按钮点击时触发 | - |
| memberClick | 点击成员时触发 | member: TeamMember |
| addClick | 点击添加按钮时触发 | - |
| readRulesClick | 点击参赛必读时触发 | - |
# Slots
| 插槽名 | 说明 | 参数 |
|---|---|---|
| foot-btn | 自定义底部按钮区域 | - |
# CSS 变量
组件提供了下列 CSS 变量,可用于自定义样式:
# 间距系统
| CSS 变量 | 说明 | 默认值 |
|---|---|---|
| --pmjtp-title-icon-ml | 标题图标间距 | $spacing-xs |
# 颜色系统
| CSS 变量 | 说明 | 默认值 |
|---|---|---|
| --pmjtp-bg-color | 背景色 | #fff |
| --pmjtp-ctrls-text-color | 控制按钮颜色 | $color-text-invert-default |
# 字体系统
| CSS 变量 | 说明 | 默认值 |
|---|---|---|
| --pmjtp-ctrls-font-size | 控制按钮字体大小 | $font-size-sm |
| --pmjtp-ctrls-icon-size | 控制按钮图标大小 | $font-size-sm |
# 使用示例
/* 自定义加入战队弹窗样式 */
:root {
--pmjtp-bg-color: #f5f5f5;
--pmjtp-ctrls-text-color: #1890ff;
--pmjtp-title-icon-ml: 8px;
}
/* 或通过customClass覆盖 */
.custom-join-team-popup {
--pmjtp-ctrls-font-size: 16px;
--pmjtp-ctrls-icon-size: 18px;
}
# 使用场景
# 1. 战队招募
- 展示战队成员信息
- 允许用户申请加入战队
- 提供参赛规则查看入口
# 2. 团队管理
- 查看战队当前成员状态
- 支持邀请新成员加入
- 管理战队人员配置
# 3. 比赛报名
- 通过加入战队参与比赛
- 了解战队实力和成员
- 确认参赛资格和规则
# 注意事项
- 战队数据:确保传入完整的战队数据结构
- 成员头像:建议使用高清头像图片,尺寸建议 80x80 像素以上
- 权限控制:根据用户权限显示不同的操作按钮
- 状态管理:合理处理战队满员、招募中等不同状态
- 小程序兼容:支持微信小程序的 virtualHost 配置
- 响应式设计:组件会根据成员数量自动调整布局
# 依赖组件
PressMatchPopUp:基础弹窗组件PressButton:按钮组件PressMatchTeamItem:战队成员展示组件