700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Vue 实现全选 多选 单选效果

Vue 实现全选 多选 单选效果

时间:2018-11-10 13:26:17

相关推荐

Vue 实现全选 多选 单选效果

需求

假如这里有多个卡片,点击相应卡片之后需要提交卡片内信息,我们需要把点击的卡片筛选出来,在不使用组件库的前提下实现全选,多选,单选操作(其中全选和多选为一个需求,单选为一个需求)

全选+多选

思路

首先我们需要给全选设置一个状态(showAllSelected),用此状态来控制全显是否点击。那怎么控制每个卡片的状态呢?由于数据是后端请求得到,我们需要对请求的数据进行改造,添加checked属性来控制是否点击每个卡片。

代码实现

HTML

<!-- 多选 --><template><div style="display: flex"><span>全选</span><span:style="{backgroundColor: showAllSelected ? '#009aff' : '#fff',borderColor: showAllSelected ? 'transparent' : 'black',}"class="circle"@click="handleselectedAll">{{ showAllSelected ? '√' : '' }}</span></div><div class="item-detail" v-for="(tmp, index) in itemData" :key="index"><div class="module-item"><span>序号:{{ tmp.flowOrder }}</span><span:style="{backgroundColor: tmp.checked ? '#009aff' : '#fff',borderColor: tmp.checked ? 'transparent' : 'black',}"class="circle"@click="handleMultiple(index)">{{ tmp.checked ? '√' : '' }}</span></div></div></template>

首先对后端请求数据进行改造,为每个item添加checked属性

handleData() {let returnData = [{flowOrder: 1,},{flowOrder: 2,},{flowOrder: 3,},]returnData.forEach((item) => {item.checked = false})this.itemData = returnData},

全选

showAllSelected: false, 用来控制全选。

当点击全选时,首先对全选状态取反,当我们第一次点击全选,下面的子项要全部选中,再次点击全选,子项也要改变,所以子项的状态和全选状态完全一致,直接对每个子项赋值为全选的状态即可。

// 全选handleselectedAll() {// 每次点击将选择框状态改变为全选状态即可this.showAllSelected = !this.showAllSelectedthis.itemData.forEach((item) => {item.checked = this.showAllSelected})},

点击全选之后的效果

再次点击效果

可以看到全选多次点击效果已经实现了~

多选

多选就是去点击每个子项,子项之间互相不干扰。注意当子项全部被选中时,全选也要被选中, 子项没有被全部选中时,全选状态为false。

当选中当前子项,对当前子项的状态进行取反。

每次点击都要判断是否所有的子项被选中,对每次判断状态赋值给全选的状态即可,every函数功能为只有当所有条件成立才会返回true,有一项不成立就返回false,符合我们的需求。

// 多选handleMultiple(index) {// 点击将相应状态改变this.itemData[index].checked = !this.itemData[index].checked// 每次点击判断是否全部选中,将状态赋值给let isSelectedAll = this.itemData.every((item) => item.checked)this.showAllSelected = isSelectedAll},

没有全部选中

全部选中

我们看到多选状态也实现了。同时全选状态也会跟着变化呢~

提交

点击提交之后拿到相应数据,只需要把 checked 为true的筛选出来即可。

// 提交submit() {let data = this.itemData.filter((item) => item.checked)console.log('data: ', data)},

单选

思路

单选和多选不一致,每次只能点击一个,再次点击当前的,需要状态取反。

因为第二次不一定点击当前这个还是其他的,所有需要设置一个currentIndex来标识是不是当前index,如果是就进行取反,如果不是就让先让所有的状态取消,设置当前状态为true即可。

代码实现

HTML

<!-- 单选 --><template><div class="item-detail" v-for="(tmp, index) in itemData" :key="index"><div class="module-item"><span>序号:{{ tmp.flowOrder }}</span><span:style="{backgroundColor: tmp.checked ? '#009aff' : '#fff',borderColor: tmp.checked ? 'transparent' : 'black',}"class="circle"@click="handleSingle(index)">{{ tmp.checked ? '√' : '' }}</span></div></div></template>

currentIndex 标识当前 index

handleSingle(index) {// 如果是当前项取反if (this.currentIndex === index) {this.itemData[index].checked = !this.itemData[index].checked} else {// 不是先取消所有状态this.itemData.forEach((item) => {item.checked = false})// 当前项设置为truethis.itemData[index].checked = true}//记录当前indexthis.currentIndex = index},

效果

提交

点击提交之后拿到相应数据,只需要把checked为true的筛选出来即可。

// 提交submit() {let data = this.itemData.filter((item) => item.checked)console.log('data: ', data)},

我们看到单选效果也实现了~

所有源码

这里附上全部代码,感兴趣的小伙伴可以自己试试,如果感觉对你有帮助,可以给作者点下赞呢~

<template><div><!-- 多选 --><template v-if="false"><div style="display: flex"><span>全选</span><span:style="{backgroundColor: showAllSelected ? '#009aff' : '#fff',borderColor: showAllSelected ? 'transparent' : 'black',}"class="circle"@click="handleselectedAll">{{ showAllSelected ? '√' : '' }}</span></div><div class="item-detail" v-for="(tmp, index) in itemData" :key="index"><div class="module-item"><span>序号:{{ tmp.flowOrder }}</span><span:style="{backgroundColor: tmp.checked ? '#009aff' : '#fff',borderColor: tmp.checked ? 'transparent' : 'black',}"class="circle"@click="handleMultiple(index)">{{ tmp.checked ? '√' : '' }}</span></div></div></template><!-- 单选 --><template><div class="item-detail" v-for="(tmp, index) in itemData" :key="index"><div class="module-item"><span>序号:{{ tmp.flowOrder }}</span><span:style="{backgroundColor: tmp.checked ? '#009aff' : '#fff',borderColor: tmp.checked ? 'transparent' : 'black',}"class="circle"@click="handleSingle(index)">{{ tmp.checked ? '√' : '' }}</span></div></div></template></div></template><script>export default {name: 'DataTest',data() {return {itemData: [],showAllSelected: false,currentIndex: -1,}},created() {this.handleData()},methods: {// 多选handleMultiple(index) {// 点击将相应状态改变this.itemData[index].checked = !this.itemData[index].checked// 每次点击判断是否全部选中,将状态赋值给let isSelectedAll = this.itemData.every((item) => item.checked)this.showAllSelected = isSelectedAll},// 全选handleselectedAll() {// 每次点击将选择框状态改变为全选状态即可this.showAllSelected = !this.showAllSelectedthis.itemData.forEach((item) => {item.checked = this.showAllSelected})},// 单选handleSingle(index) {// 如果是当前项取反if (this.currentIndex === index) {this.itemData[index].checked = !this.itemData[index].checked} else {// 不是先取消所有状态this.itemData.forEach((item) => {item.checked = false})// 当前项设置为truethis.itemData[index].checked = true}//记录当前indexthis.currentIndex = index},// 初始化数据handleData() {let returnData = [{flowOrder: 1,},{flowOrder: 2,},{flowOrder: 3,},]returnData.forEach((item) => {item.checked = false})this.itemData = returnData},},}</script><style scoped>.module-item {display: flex;justify-content: space-between;align-items: center;padding: 10px;margin: 10px;border: 1px solid #409eff;border-radius: 8px;}.circle {display: flex;justify-content: center;align-items: center;border-width: 1px;border-style: solid;border-radius: 50%;color: #fff;width: 20px;height: 20px;margin-left: 10px;line-height: 35px;text-align: center;}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。