我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了!
项目效果
项目实现
html
- 上方用v-for遍历所有座位,用动态class标记已选择的座位
- em斜体标签为右上方座位序号
- 下方用v-for遍历已选中的座位
<div class="seat-container">
<!-- 上方所有座位 -->
<div class="seats-box">
<span v-for="item in seatArr" :key="'座位序号' + item.id"
@click="selectSeatFn(item.id)" :class="{'active-seat': item.seat === '座位已选'}">
{{item.seat}}
<em>{{item.id}}</em>
</span>
</div>
<div class="screen">电影屏幕</div>
<span>已选序号座位(点击上方小方块选择座位)</span>
<!-- 下方所有选中的座位 -->
<div class="select-seat">
<span v-for="item in selectArr"
:key="'座位已选序号' + item">{{item}}</span>
</div>
</div>
script
- 只贴了核心代码,提示在代码旁边
- 逻辑不是很难
// 点击上方小方块
selectSeatFn (index) { // index点击小方块的序号
this.seatArr.forEach(item => {
if (item.id === index && item.seat === '座位未选') { // 点击选择座位
item.seat = '座位已选' // 替换文字
} else if (item.id === index && item.seat === '座位已选') { // 点击取消座位
item.seat = '座位未选' // 替换文字
}
})
this.seatArr.forEach(item => {
if (item.seat === '座位已选' && !this.selectArr.includes(item.id)) {
this.selectArr.unshift(item.id) // 将选中的座位序号加到数组中
} else if (this.selectArr.includes(item.id) && item.seat === '座位未选') {
// 将取消座位的序号过滤掉
this.selectArr = this.selectArr.filter(selectItem => selectItem !== item.id)
}
})
}
css
- 只贴了上方代码
- 布局用了弹性布局和一点定位, 其他都是很常用的属性
- user-select: none; =>元素和子元素的文本将无法被选中
.active-seat{
background: red!important; // 注意权重
color: #fff!important;
}
.seat-container{
width: 650px;
padding: 20px;
margin: auto;
border: 2px solid #eee;
text-align: center;
user-select: none; // 禁选文字,防止点击时选中文字,影响视觉效果
// 上方代码
.seats-box{
display: flex;
width: 100%;
justify-content: space-around;
flex-wrap: wrap;
span{
position: relative;
flex: 18%;
height: 50px;
margin: 10px;
background-color: #eee;
color: #666;
line-height: 50px; // 大小应于高度一致,才能保证垂直居中效果
cursor: pointer;
em{
position: absolute;
top: -16px; // 抵消父元素的行高效果
right: 2px;
color: pink;
font-size: 12px;
}
}
}
}