feat: 游戏列表组件+基础样式

This commit is contained in:
2026-06-18 10:15:13 +08:00
parent 33c2b31117
commit 3bc3cce62a
6 changed files with 258 additions and 10 deletions

8
components.d.ts vendored
View File

@@ -22,9 +22,11 @@ declare module 'vue' {
ElInput: typeof import('element-plus/es')['ElInput']
ElInputOtp: typeof import('element-plus/es')['ElInputOtp']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
GameList: typeof import('./src/components/baseLayouts/GameList.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
UserBar: typeof import('./src/components/User/UserBar.vue')['default']
UserBar: typeof import('./src/components/baseLayouts/UserBar.vue')['default']
}
}
@@ -40,7 +42,9 @@ declare global {
const ElInput: typeof import('element-plus/es')['ElInput']
const ElInputOtp: typeof import('element-plus/es')['ElInputOtp']
const ElPopover: typeof import('element-plus/es')['ElPopover']
const ElTooltip: typeof import('element-plus/es')['ElTooltip']
const GameList: typeof import('./src/components/baseLayouts/GameList.vue')['default']
const RouterLink: typeof import('vue-router')['RouterLink']
const RouterView: typeof import('vue-router')['RouterView']
const UserBar: typeof import('./src/components/User/UserBar.vue')['default']
const UserBar: typeof import('./src/components/baseLayouts/UserBar.vue')['default']
}

View File

@@ -2,4 +2,52 @@
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,
body {
height: 100%;
width: 100%;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
line-height: 1.5;
color: #333;
background-color: #fff;
}
#app {
height: 100%;
}
a {
color: inherit;
text-decoration: none;
}
ul,
ol {
list-style: none;
}
img {
max-width: 100%;
height: auto;
display: block;
}
button {
cursor: pointer;
border: none;
background: none;
font: inherit;
color: inherit;
}
input {
font: inherit;
color: inherit;
}

View File

@@ -0,0 +1,199 @@
<template>
<div class="game-list">
<!-- 左侧游戏图标列表 -->
<div class="game-list__icons">
<el-tooltip
v-for="game in games"
:key="game.id"
:content="game.name"
placement="right"
:show-after="300"
>
<div
class="game-list__icon-item"
:class="{ 'game-list__icon-item--active': activeGameId === game.id }"
@click="selectGame(game.id)"
>
<span class="game-list__icon-emoji">{{ game.icon }}</span>
</div>
</el-tooltip>
</div>
<!-- 右侧游戏详情 -->
<div class="game-list__detail">
<template v-if="activeGame">
<h3 class="game-list__detail-title">{{ activeGame.name }}</h3>
<p class="game-list__detail-desc">{{ activeGame.description }}</p>
<div class="game-list__detail-gameplay">
<h4>玩法介绍</h4>
<p>{{ activeGame.gameplay }}</p>
</div>
</template>
<div v-else class="game-list__detail-empty">
<p>请选择一个游戏</p>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
/** 游戏数据接口 */
interface GameInfo {
id: string
/** 图标emoji 或文字占位) */
icon: string
name: string
description: string
gameplay: string
}
/** 游戏列表数据 */
const games: GameInfo[] = [
{
id: 'basketball',
icon: '🏀',
name: '篮球对决',
description: '实时篮球对战游戏,与全球玩家同场竞技',
gameplay: '使用方向键移动球员空格键投篮。每场比赛5分钟得分多者获胜。支持1v1、3v3模式。'
},
{
id: 'football',
icon: '⚽',
name: '足球竞技',
description: '热血足球比赛,组建你的梦之队',
gameplay: 'WASD控制球员移动J键传球K键射门。11人制比赛配合战术赢得胜利。'
},
{
id: 'racing',
icon: '🏎️',
name: '极速赛车',
description: '极限竞速,漂移过弯超越对手',
gameplay: '方向键控制方向Shift键加速漂移。多种赛道可选挑战最快圈速记录。'
},
{
id: 'chess',
icon: '♟️',
name: '策略棋牌',
description: '经典棋牌合集,运筹帷幄决胜千里',
gameplay: '包含围棋、象棋、五子棋等多种棋类。支持人机对战和在线匹配两种模式。'
},
{
id: 'shooting',
icon: '🎯',
name: '射击战场',
description: '团队战术射击,配合队友夺取胜利',
gameplay: '鼠标瞄准左键射击R键换弹。多种武器和地图5v5团队竞技模式。'
},
{
id: 'arena',
icon: '🏆',
name: '竞技场',
description: '综合竞技平台,参与锦标赛赢取奖励',
gameplay: '每日举办多场锦标赛,涵盖各类型游戏。积累积分提升段位,赢取丰厚奖励。'
}
]
/** 当前选中的游戏 ID */
const activeGameId = ref<string>('basketball')
/** 当前选中的游戏对象 */
const activeGame = computed(() => games.find((g) => g.id === activeGameId.value) ?? null)
/** 选择游戏 */
function selectGame(id: string) {
activeGameId.value = id
}
</script>
<style scoped lang="scss">
.game-list {
display: flex;
height: 100%;
width: 100%;
color: #fff;
}
/* ===== 左侧图标列表 ===== */
.game-list__icons {
display: flex;
flex-direction: column;
gap: 4px;
width: 60px;
flex-shrink: 0;
padding: 8px 4px;
overflow-y: auto;
border-right: 1px solid rgba(255, 255, 255, 0.15);
}
.game-list__icon-item {
display: flex;
align-items: center;
justify-content: center;
width: 48px;
height: 48px;
border-radius: 12px;
cursor: pointer;
transition: background-color 0.2s ease;
&:hover {
background-color: rgba(255, 255, 255, 0.15);
}
&--active {
background-color: rgba(255, 255, 255, 0.25);
}
}
.game-list__icon-emoji {
font-size: 24px;
line-height: 1;
user-select: none;
}
/* ===== 右侧详情面板 ===== */
.game-list__detail {
flex: 1;
padding: 16px;
overflow-y: auto;
}
.game-list__detail-title {
font-size: 22px;
font-weight: 600;
margin-bottom: 12px;
text-align: center;
}
.game-list__detail-desc {
font-size: 14px;
line-height: 1.6;
color: rgba(255, 255, 255, 0.8);
margin-bottom: 24px;
}
.game-list__detail-gameplay {
h4 {
font-size: 16px;
font-weight: 500;
margin-bottom: 8px;
color: rgba(255, 255, 255, 0.9);
}
p {
font-size: 13px;
line-height: 1.7;
color: rgba(255, 255, 255, 0.7);
}
}
.game-list__detail-empty {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
}
</style>

View File

@@ -8,7 +8,9 @@
<!-- 侧边栏 -->
<div class="base-layout__sidebar">
<!-- 侧边栏内容 -->
<div class="base-layout__sidebar-content"></div>
<div class="base-layout__sidebar-content">
<GameList />
</div>
<!-- 侧边栏底部固定区域 -->
<div class="base-layout__sidebar-bottom">
<div class="base-layout__sidebar-bottom-inner">
@@ -26,7 +28,8 @@
</template>
<script setup lang="ts">
import UserBar from '@/components/User/UserBar.vue'
import UserBar from '@/components/baseLayouts/UserBar.vue'
import GameList from '@/components/baseLayouts/GameList.vue'
</script>
<style scoped lang="scss">

View File

@@ -1,6 +0,0 @@
<template>
<main>
<div>你好呀</div>
</main>
</template>
<script setup lang="ts"></script>