2 changed files with 313 additions and 7 deletions
@ -1,7 +1,313 @@ |
|||
<template> |
|||
<view>我的选举</view> |
|||
<view class="container"> |
|||
<view v-for="(item, index) in electionList" :key="index" class="election-item"> |
|||
<view class="year-title"> |
|||
<view class="headpart"> |
|||
<text class="title">{{ item.title }}</text> |
|||
<view class="type" |
|||
:style="item.type=='投票中'? 'background: #DBEAFE;color: #3B82F6;' : (item.type=='当选'? 'background: #DCFCE7;color: #10B981' : 'background: #F3F4F6;color: #4B5563')"> |
|||
{{item.type}} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view class="flex-center-between" style="display: flex;"> |
|||
<view style="display: grid;"> |
|||
<view |
|||
v-for="(candidate, cIndex) in item.candidates.slice(0, expandedStates[index] ? item.candidates.length : 1)" |
|||
:key="cIndex" class="candidate-item"> |
|||
<view class="info-section"> |
|||
<view style="display: flex;align-items: center;"> |
|||
<img style="width: 96rpx;height: 96rpx;border-radius: 50%;" :src="item.img" alt="" /> |
|||
<view style="margin-left: 24rpx;display: grid;"> |
|||
<text class="name">{{ candidate.name }}</text> |
|||
<text class="college">{{ candidate.college }}</text> |
|||
</view> |
|||
</view> |
|||
<view style="display: flex;margin-top: 24rpx;"> |
|||
我的选择:<view :class="['choice-tag', choiceClass(candidate.choice)]"> |
|||
{{ choiceText(candidate.choice) }} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
<view class="expand-btn" @click="toggleExpand(index)"> |
|||
<text :class="['arrow', expandedStates[index] ? 'up' : 'down']"></text> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script lang="ts" setup></script> |
|||
<script setup> |
|||
import { |
|||
ref, |
|||
watch |
|||
} from 'vue' |
|||
|
|||
|
|||
const electionList = ref([{ |
|||
type: "投票中", |
|||
title: "2024学生会主席选举", |
|||
candidates: [{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远", |
|||
college: "计算机科学与技术学院", |
|||
choice: 1 |
|||
}, |
|||
{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远2号", |
|||
college: "计算机科学与技术学院", |
|||
choice: 0 |
|||
}, |
|||
{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远2号", |
|||
college: "计算机科学与技术学院", |
|||
choice: 2 |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
type: "投票中", |
|||
title: "2024学生会主席选举", |
|||
candidates: [{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远", |
|||
college: "计算机科学与技术学院", |
|||
choice: 1 |
|||
}, |
|||
{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远2号", |
|||
college: "计算机科学与技术学院", |
|||
choice: 0 |
|||
}, |
|||
{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远2号", |
|||
college: "计算机科学与技术学院", |
|||
choice: 2 |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
type: "投票中", |
|||
title: "2024学生会主席选举", |
|||
candidates: [{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远", |
|||
college: "计算机科学与技术学院", |
|||
choice: 1 |
|||
}, |
|||
{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远2号", |
|||
college: "计算机科学与技术学院", |
|||
choice: 0 |
|||
}, |
|||
{ |
|||
img: '../../static/redpacket.png', |
|||
name: "陈思远2号", |
|||
college: "计算机科学与技术学院", |
|||
choice: 2 |
|||
} |
|||
] |
|||
}, |
|||
{ |
|||
type: "当选", |
|||
title: "2023优秀班干部评选", |
|||
candidates: [{ |
|||
img: '../../static/redpacket.png', |
|||
name: "李雨晴", |
|||
college: "工商管理学院", |
|||
choice: 0 |
|||
}] |
|||
}, |
|||
{ |
|||
type: "未当选", |
|||
title: "2023最佳社团负责人", |
|||
candidates: [{ |
|||
img: '../../static/redpacket.png', |
|||
name: "王浩然", |
|||
college: "艺术设计学院", |
|||
choice: 2 |
|||
}] |
|||
} |
|||
]) |
|||
|
|||
// 展开状态管理 |
|||
const expandedStates = ref([]) |
|||
watch(() => electionList.value, (newVal) => { |
|||
expandedStates.value = newVal.map(() => false) |
|||
}, { |
|||
immediate: true |
|||
}) |
|||
|
|||
const toggleExpand = (index) => { |
|||
expandedStates.value[index] = !expandedStates.value[index] |
|||
} |
|||
|
|||
const choiceClass = (choice) => { |
|||
switch (choice) { |
|||
case 1: |
|||
return 'agree'; |
|||
case 0: |
|||
return 'oppose'; |
|||
case 2: |
|||
return 'abstain'; |
|||
default: |
|||
return ''; |
|||
} |
|||
} |
|||
|
|||
const choiceText = (choice) => { |
|||
return { |
|||
1: '同意', |
|||
0: '反对', |
|||
2: '弃权' |
|||
} [choice] || '' |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.container { |
|||
padding: 20rpx; |
|||
background-color: #F9FAFB; |
|||
height: 100vh; |
|||
} |
|||
|
|||
.election-item { |
|||
margin-bottom: 30rpx; |
|||
padding: 40rpx; |
|||
border-radius: 24rpx; |
|||
background: linear-gradient(0deg, rgba(0, 0, 0, 0.001), rgba(0, 0, 0, 0.001)), #FFFFFF; |
|||
box-sizing: border-box; |
|||
border: 2rpx solid #F3F4F6; |
|||
box-shadow: 0rpx 2rpx 4rpx 0rpx rgba(0, 0, 0, 0.05); |
|||
} |
|||
|
|||
.year-title { |
|||
font-size: 32rpx; |
|||
font-weight: bold; |
|||
color: #333; |
|||
|
|||
.headpart { |
|||
width: 100%; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
|
|||
.title { |
|||
font-family: Roboto; |
|||
font-size: 32rpx; |
|||
font-weight: 500; |
|||
letter-spacing: normal; |
|||
color: #000000; |
|||
} |
|||
|
|||
.type { |
|||
font-family: Roboto; |
|||
font-size: 24rpx; |
|||
font-weight: normal; |
|||
/* 自动布局 */ |
|||
display: flex; |
|||
flex-direction: column; |
|||
padding: 4rpx 16rpx; |
|||
gap: 0rpx 20rpx; |
|||
flex-wrap: wrap; |
|||
align-content: flex-start; |
|||
border-radius: 24rpx; |
|||
} |
|||
} |
|||
} |
|||
|
|||
.candidate-item { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
padding: 20rpx 0; |
|||
} |
|||
|
|||
.info-section { |
|||
flex: 1; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.name { |
|||
font-family: Roboto; |
|||
font-size: 28rpx; |
|||
font-weight: 500; |
|||
letter-spacing: normal; |
|||
color: #000000; |
|||
} |
|||
|
|||
.college { |
|||
font-family: Roboto; |
|||
font-size: 24rpx; |
|||
font-weight: normal; |
|||
letter-spacing: normal; |
|||
color: #6B7280; |
|||
} |
|||
|
|||
.choice-tag { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
font-family: Roboto; |
|||
font-size: 28rpx; |
|||
font-weight: normal; |
|||
} |
|||
|
|||
.agree { |
|||
color: #3B82F6; |
|||
} |
|||
|
|||
.oppose { |
|||
color: #F44336; |
|||
} |
|||
|
|||
.abstain { |
|||
color: #9CA3AF; |
|||
} |
|||
|
|||
.year-title { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
} |
|||
|
|||
.expand-btn { |
|||
display: flex; |
|||
align-items: center; |
|||
color: #666; |
|||
font-size: 26rpx; |
|||
padding: 10rpx 20rpx; |
|||
} |
|||
|
|||
.arrow { |
|||
display: inline-block; |
|||
width: 0; |
|||
height: 0; |
|||
margin-left: 10rpx; |
|||
border-left: 10rpx solid transparent; |
|||
border-right: 10rpx solid transparent; |
|||
} |
|||
|
|||
.down { |
|||
border-top: 15rpx solid #999; |
|||
} |
|||
|
|||
.up { |
|||
border-bottom: 15rpx solid #999; |
|||
} |
|||
|
|||
<style lang="scss" scoped></style> |
|||
/* 优化候选人项间距 */ |
|||
.candidate-item:last-child { |
|||
border-bottom: none; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue