vue v-for模板如何自定义实现全选,反全选功能

155 阅读2分钟

需求:实现单个勾选,反勾选,全选反选功能,废话不多少,并实时更新选中id集合,直接上代码。

image.png

<template>
	<view class="main-container">
		<u-navbar :title="title"></u-navbar>
		<view @click="getTab" class="mt-50">
			<u-tabs :is-scroll="isScroll" class="u-tabs" :class="isScroll ? '' : 'no-scroll-tab'" :current="currentTabIndex" :list="tabList" @change="tabChange"></u-tabs>
		</view>
		<u-calendar v-if="timePicKFlag" v-model="timePicKFlag" :mode="mode" @change="getSure"></u-calendar>
		<scroll-view v-if="orderList.length > 0" class="scroll-box" :class="selectOrderArr.length > 0 ? 'customer-scroll' : ''" :scroll-top="0" scroll-y="true" @scrolltolower="scrolltolower" refresher-enabled="true" :refresher-triggered="trigger" @refresherrefresh="refresherrefresh">
			<view class="order-list" v-for="(item, index) in orderList" :key="index" @click.stop="getDetail(item, index)">
				<view class="operate-select-box" @click.stop="getSingleSelect(item, index)">
					<image v-if="item.inboundStatus == 1 " class="select-image" mode="aspectFill" src="@/static/images/disabled-img.png"></image>
					<view class="default-img" v-else>
						<image v-if="item.checkImgFlag" class="select-image" mode="aspectFill" src="@/static/images/check-img.png"></image>
						<image v-if="!item.checkImgFlag && orderList.length > 1" class="select-image" mode="aspectFill" src="@/static/images/defult-img.png"></image>
					</view>
					<view class="order-desc">订单号:{{ item.orderNo }}</view>
				</view>
				<view class="flex">
					<view class="waste-item" v-for="(dt, index) in item.orderDetailsList" :key="index">
						<view class="waste-name">{{ dt.categoryName }}*{{ dt.actualWeight }}{{ dt.unit }}</view>
						<view class="waste-price">¥{{ dt.unitPrice/100 }}</view>
					</view>
				</view>
				<view class="main-info">
					<view>完成时间:{{ item.endTime }}</view>
					<view class="">支付类型:{{ item.settleType == 0 ? '现金支付' : '微信支付' }}</view>
					<view>应付:{{ item.actualPaymentAmount }}</view>
					<view class="info-item">实付:{{ item.amount }}</view>
				</view>
				<view class="flex-order-type" @click.stop="getPutStore(item)">
					<view class="order-source">{{ item.orderSource == 0 ? '上门订单' : '门店订单' }}</view>
					<view class="common-btn" :class="item.inboundStatus == 0 ? '' : 'disabled-btn'">{{ item.inboundStatus == 0 ? '入库' : '已入库' }}</view>
				</view>
				<view class="order-type" :class="item.status == 0 ? 'public-style' : 'paid-style'">{{ item.orderType == 0 ? '公益' : '有偿' }}</view>
			</view>
			</scroll-view>
			<view v-if="selectOrderArr.length > 0 || batchSelectIds.length > 0" class="bottom-nav">
				<view class="flex" @click="getSlectAll">
					<view class="flex-check">
						<image v-if="allSelectFlag" class="select-image" mode="aspectFill" src="@/static/images/check-img.png"></image>
						<image v-else class="select-image" mode="aspectFill" src="@/static/images/defult-img.png"></image>
						<view class="select-tip">全选 {{ batchSelectIds.length }} 个订单</view>
					</view>
				</view>
				<view class="common-btn over-btn" @click="getStorePut">入库</view>
			</view>
			<view v-if=" orderList.length == 0" class="empty-box-center" >
				<u-empty text="暂无数据" mode="favor"></u-empty>
			</view>
		<lf-back-top :show-tag="showTag"></lf-back-top>
	</view>
</template>

<script>

	export default {
		data() {
			return {
				orderIds: [],
				mode: 'range',
				pageType: '',
				params: {
					year: true,
					month: true,
					day: true,
					hour: false,
					minute: false,
					second: false
				},
				trigger: true,
				batchSelectIds: [],
				allSelectFlag: false,
				selectOrderArr: [],
				currentTabIndex: 0,
				pageNo: 1,
				pageSize: 10,
				resultArr: [],
				showTag: false,
				timePicKFlag: false,
				tabList: [
					{ name: '全部' },
					{ name: '已入库' },
					{ name: '未入库' },
					{ name: '时间筛选' },
				],
				orderList: [],
				title: '入库订单'
			};
		},
		onLoad(options) {
			let tabBackIndex = uni.getStorageSync('backTabIndex')
			if (tabBackIndex) {
				this.currentTabIndex = tabBackIndex
				this.tabChange(this.currentTabIndex)
			} else {
				this.currentTabIndex = 0
				this.getInit()
			}
			this.allSelectFlag = false
			setTimeout(() => {
				uni.removeStorageSync('backTabIndex')
			}, 1000)
			this.pageType = options.type
		},
		onPageScroll(e) {
			this.showTag = e.scrollTop > 750
		},
		methods: {
			scrolltolower(e) {
				console.log(e, '1111')
				if (this.resultArr.length > 1) {
					this.pageNo++
					this.getInit()
				}
			},
			refresherrefresh() {
				this.trigger = true;
				this.pageNo = 1
				setTimeout(() => {
					this.resultArr = []
					this.orderList = []
					this.getInit()
				  this.trigger = false;
				}, 1000);
			},
			tabChange(index) {
				this.pageNo = 1
				this.orderList = []
				this.endDate = undefined
				this.startDate = undefined
				this.inboundStatus = undefined
				switch(index) {
					case 1:
						this.inboundStatus = 1
						break
					case 2:
						this.inboundStatus = 0
						break
				}
				this.currentTabIndex = index;
				this.getInit()
			},
			getTab() {
				if (this.currentTabIndex == 3) {
					this.timePicKFlag = true
				}
			},
			getInit() {
				this.$H.post('/app-api/recycling/app/recycler-manager/recyclerAllOrder', {
					pageNo: this.pageNo,
					endDate: this.endDate,
					pageSize: this.pageSize,
					startDate: this.startDate,
					inboundStatus: this.inboundStatus,
				}).then(res => {
					if (res.code == 0) {
						res.data.list.forEach((item) => {
							item.checkImgFlag = false
							let date = new Date(item.finishTime)
							item.endTime =  date.getFullYear() + '-' + (date.getMonth() + 1) + '-' + date.getDate();
						})
						this.resultArr = res.data.list
						this.orderList = this.orderList.concat(res.data.list)
					} else {
						uni.showToast({
							title: res.msg,
							icon: "none",
							duration: 2000
						})
					}
				})
			},
			// 跳转详情
			getDetail(data, index) {
				this.getOrderIds(data)
				uni.setStorageSync('currentTabIndex', this.currentTabIndex)
				uni.navigateTo({
					url: `/pages/putStore/putStore?orderNo=${data.orderNo}`
				})
			},
			// 点击默认图标单选
			getSingleSelect(data, index) {
				if (this.orderList.length > 1) {
					let deleteIndex = -1
					this.orderList[index].checkImgFlag = !this.orderList[index].checkImgFlag
					// 已全选
					if (this.allSelectFlag) {
						// 删除全选数组中,当前单选id
						deleteIndex = this.batchSelectIds.indexOf(data.id)
						this.getImgSingle(data, index, this.batchSelectIds, deleteIndex)
					} else {
						deleteIndex = this.selectOrderArr.indexOf(data.id)
						// 未全选
						this.getImgSingle(data, index, this.selectOrderArr, deleteIndex)
					}
				}
			},
			getImgSingle(data, index, selectData, deleteIndex) {
				// 选中
				if (this.orderList[index].checkImgFlag) {
					selectData.push(this.orderList[index].id)
					// 取消选中
				} else {
					 selectData.splice(deleteIndex, 1)
				}
				this.batchSelectIds = selectData
			},
			getSlectAll() {
				this.allSelectFlag = !this.allSelectFlag
				this.orderList.forEach((item) => {
					item.checkImgFlag = true
					// 全选
					if (this.allSelectFlag) {
						if (item.checkImgFlag && item.inboundStatus !== 1) {
							this.selectOrderArr.push(item.id)
						}
						// 全反选
					} else {
						item.checkImgFlag = false
						this.selectOrderArr = []
					}
					
				})
				this.batchSelectIds = Array.from(new Set(this.selectOrderArr))
			},
			getPutStore(data) {
				this.getOrderIds(data)
				uni.navigateTo({
					url: '/pages/putSureStore/putSureStore'
				})
			},
			getOrderIds(data) {
				this.orderIds = []
				this.orderIds.push(data.id)
				uni.setStorageSync('selectOrderId', this.orderIds)
			},
			getStorePut() {
				uni.setStorageSync('selectOrderId', this.batchSelectIds)
				uni.setStorageSync('selectOrderId', this.batchSelectIds)
				uni.navigateTo({
					url: '/pages/putSureStore/putSureStore'
				})
			},
			getSure(data) {
				if (!data.startDate) {
					uni.showToast({
						title: '请选择结束时间',
						icon: "none",
						duration: 1000
					})
				} else if (!data.endDate) {
					uni.showToast({
						title: '请选择开始时间',
						icon: "none",
						duration: 1000
					})
				} else {
					this.pageNo = 1
					this.orderList = []
					this.endDate = data.endDate
					this.startDate = data.startDate
					this.getInit()
				}
			}
		}
	};
</script>

<style lang="scss" scoped>
	.main-container {
		height: 100%;
		background: linear-gradient( 180deg, #C4FFD6 0%, #F7F7F7 50%);
		.select-image {
			width: 40rpx;
			height: 40rpx;
			margin-right: 8rpx;
		}
		.default-img {
			height: 45rpx;
		}
		.customer-scroll {
			padding-bottom: 177rpx;
		}
		.scroll-box {
			height: 1255rpx;
			overflow-y: scroll;
			border-radius: 24rpx;
			.order-list {
				padding: 24rpx;
				margin-bottom: 24rpx;
				background: #FFFFFF;
				position: relative;
				border-radius: 24rpx 24rpx 24rpx 24rpx;
				.operate-select-box {
					display: flex;
					align-items: center;
				}
				.order-desc {
					font-weight: 600;
					font-size: 32rpx;
				}
				.flex {
					flex-wrap: wrap;
					margin-top: 24rpx;
					border-bottom: 2rpx solid #EEEEEE;
					.waste-item {
						text-align: center;
						background: #F4F4F4;
						padding: 8rpx 40rpx;
						width: fit-content;
						margin: 0 24rpx 24rpx 0;
						border-radius: 24rpx 24rpx 24rpx 24rpx;
						.waste-name {
							font-size: 30rpx;
						}
						.waste-price {
							font-size: 25rpx;
							color: rgba(0,0,0,0.4);
						}
					}
				}
				.main-info {
					color: #7D7D7D;
					font-size: 28rpx;
					margin-top: 13rpx;
					.info-item {
						font-weight: 600;
						color: #000000;
						font-size: 28rpx;
					}
				}
				.flex-order-type {
					display: flex;
					align-items: center;
					margin-top: 24rpx;
					justify-content: space-between;
					.order-source {
						color: #898A8D;
						font-size: 28rpx;
					}
					.common-btn {
						height: 64rpx;
						width: fit-content;
						padding: 12rpx 32rpx;
					}
				}
			}
		}
		.bottom-nav {
			justify-content: space-between;
			.flex {
				align-items: center;
				.flex-check {
					display: flex;
					align-items: center;
					.select-tip {
						font-size: 28rpx;
						font-weight: 600;
					}
				}
			}
		}
	}
</style>

END...