6 changed files with 549 additions and 27 deletions
@ -1,7 +1,332 @@ |
|||||
<template> |
<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> |
</template> |
||||
|
|
||||
<script lang="ts" setup></script> |
<script setup> |
||||
|
import { ref, watch } from 'vue' |
||||
|
|
||||
<style lang="scss" scoped></style> |
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; |
||||
|
} |
||||
|
|
||||
|
/* 优化候选人项间距 */ |
||||
|
.candidate-item:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
</style> |
||||
|
|||||
@ -0,0 +1,181 @@ |
|||||
|
@charset "UTF-8"; |
||||
|
#app { |
||||
|
box-sizing: border-box; |
||||
|
background-color: #f5f5f5; |
||||
|
} |
||||
|
|
||||
|
/* 颜色变量 */ |
||||
|
/*============================= 文字尺寸 =============================*/ |
||||
|
image { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
view { |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
/*============================= 弹性盒子 =============================*/ |
||||
|
.flex-end-evenly, .flex-end-around, .flex-end-between, .flex-end-end, .flex-end-center, .flex-end-start, .flex-center-evenly, .flex-center-around, .flex-center-between, .flex-center-end, .flex-center-start, .flex-start-evenly, .flex-start-around, .flex-start-between, .flex-start-end, .flex-start-center, .flex-start-start, .flex { |
||||
|
display: flex; |
||||
|
flex-wrap: nowrap; |
||||
|
} |
||||
|
|
||||
|
.flex { |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
.flex-start-start { |
||||
|
align-items: flex-start; |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
.flex-start-center { |
||||
|
align-items: flex-start; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
.flex-start-end { |
||||
|
align-items: flex-start; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
.flex-start-between { |
||||
|
align-items: flex-start; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
.flex-start-around { |
||||
|
align-items: flex-start; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
.flex-start-evenly { |
||||
|
align-items: flex-start; |
||||
|
justify-content: space-evenly; |
||||
|
} |
||||
|
.flex-center-start { |
||||
|
align-items: center; |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
.flex-center-end { |
||||
|
align-items: center; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
.flex-center-between { |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
.flex-center-around { |
||||
|
align-items: center; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
.flex-center-evenly { |
||||
|
align-items: center; |
||||
|
justify-content: space-evenly; |
||||
|
} |
||||
|
.flex-end-start { |
||||
|
align-items: flex-end; |
||||
|
justify-content: flex-start; |
||||
|
} |
||||
|
.flex-end-center { |
||||
|
align-items: flex-end; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
.flex-end-end { |
||||
|
align-items: flex-end; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
.flex-end-between { |
||||
|
align-items: flex-end; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
.flex-end-around { |
||||
|
align-items: flex-end; |
||||
|
justify-content: space-around; |
||||
|
} |
||||
|
.flex-end-evenly { |
||||
|
align-items: flex-end; |
||||
|
justify-content: space-evenly; |
||||
|
} |
||||
|
|
||||
|
[class*=flex-].nowrap, |
||||
|
[class^=flex].nowrap { |
||||
|
flex-wrap: nowrap; |
||||
|
} |
||||
|
[class*=flex-].stretch, |
||||
|
[class^=flex].stretch { |
||||
|
align-items: stretch; |
||||
|
} |
||||
|
[class*=flex-].row, |
||||
|
[class^=flex].row { |
||||
|
flex-direction: row; |
||||
|
} |
||||
|
[class*=flex-].row-reverse, |
||||
|
[class^=flex].row-reverse { |
||||
|
flex-direction: "row-reverse"; |
||||
|
} |
||||
|
[class*=flex-].column, |
||||
|
[class^=flex].column { |
||||
|
flex-direction: column; |
||||
|
} |
||||
|
[class*=flex-].column-reverse, |
||||
|
[class^=flex].column-reverse { |
||||
|
flex-direction: "column-reverse"; |
||||
|
} |
||||
|
[class*=flex-].wrap, |
||||
|
[class^=flex].wrap { |
||||
|
flex-wrap: wrap; |
||||
|
} |
||||
|
[class*=flex-].wrap-reverse, |
||||
|
[class^=flex].wrap-reverse { |
||||
|
flex-wrap: "wrap-reverse"; |
||||
|
} |
||||
|
|
||||
|
.flex1 { |
||||
|
flex: 1; |
||||
|
} |
||||
|
|
||||
|
.flex2 { |
||||
|
flex: 2; |
||||
|
} |
||||
|
|
||||
|
.flex3 { |
||||
|
flex: 3; |
||||
|
} |
||||
|
|
||||
|
.flex4 { |
||||
|
flex: 4; |
||||
|
} |
||||
|
|
||||
|
/*============================= 文字溢出 =============================*/ |
||||
|
.text-ellipsis { |
||||
|
overflow: hidden; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
.text-ellipsis-2 { |
||||
|
overflow: hidden; |
||||
|
white-space: normal; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-box-orient: vertical; |
||||
|
line-clamp: 1; |
||||
|
-webkit-line-clamp: 2; |
||||
|
} |
||||
|
.text-ellipsis-3 { |
||||
|
overflow: hidden; |
||||
|
white-space: normal; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-box-orient: vertical; |
||||
|
line-clamp: 1; |
||||
|
-webkit-line-clamp: 3; |
||||
|
} |
||||
|
.text-ellipsis-4 { |
||||
|
overflow: hidden; |
||||
|
white-space: normal; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-box-orient: vertical; |
||||
|
line-clamp: 1; |
||||
|
-webkit-line-clamp: 4; |
||||
|
} |
||||
|
|
||||
|
/*# sourceMappingURL=uni.css.map */ |
||||
Loading…
Reference in new issue