index.vue 6.22 KB
<template>
	<view class="container">
		 <uv-navbar leftIcon="" placeholder bgColor="rgba(255, 255, 255, 0)">
			<template v-slot:left>
				<view class="uv-nav-slot">
					XXXX
				</view>
			</template>
		</uv-navbar>

		<view class="content-box">
			<view style="display: grid;grid-template-columns: 47.5% 47.5%;gap: 5%;">
				<view @click="showGradesPop" class="select-item">
					{{ state.grade }}<uv-icon name="arrow-down-fill" color="#7175f0" size="20"
						style="margin-left: 6rpx;"></uv-icon>
				</view>
				<view @click="showAccountsPop" class="select-item">
					{{ state.accounts }}<uv-icon name="arrow-down-fill" color="#7175f0" size="20" style="margin-left: 6rpx;"></uv-icon>
				</view>
			</view>
			
			<view class="course-list">
				<view v-for="item in state.courses" class="course-box">
					<image :src="item.img"  style="width: 160rpx;height: 160rpx;border-radius: 20rpx;"></image>
					<view style="flex: 1;display: flex;">
						<view style="flex: 1;padding: 0 20rpx;display: flex;flex-direction: column;justify-content: space-between;">
							<view style="font-size: 30rpx;">{{ item.name }} - {{ item.subject }}</view>
							<view style="color: #ff3838;font-weight: 600;">¥{{ item.price }}</view>
						</view>
						<view style="width: 160rpx;display: flex;align-items: center;justify-content: flex-end;">
								<view @click="gotoSignUp(item.id)" style="width: 100%;;background-color: #f57c28;color: #fff;text-align: center;padding: 10rpx 0;border-radius: 9999rpx;">
									去报名
								</view>
						</view>
					</view>
				</view>
			</view>
		</view>

		<!-- 年级弹窗 -->
		<uv-popup ref="gradesRef" safeAreaInsetBottom closeable :round="20">
			<view class="pop-box">
				<view class="content-pop">
					<view @click="selectGrade('全部年级')" class="pop-inner-item" style="margin: 20rpx 0;" :style="state.grade === '全部年级' ? 'border-color:#7175f0;color:#7175f0;background-color:#f6f7ff;' : ''">
						全部年级
					</view>
					<view v-for="item in state.gradOptions" style="margin-bottom: 30rpx;">
						<view class="pop-title">
							{{ item.title }}
						</view>
						<view class="pop-inner">
							<view v-for="item1 in item.content" @click="selectGrade(item1)" class="pop-inner-item"
								:style="state.grade === item1 ? 'border-color:#7175f0;color:#7175f0;background-color:#f6f7ff;' : ''">
								{{ item1 }}
							</view>
						</view>
					</view>
				</view>
			</view>
		</uv-popup>

		<!-- 科目弹窗 -->
		<uv-popup ref="accountsRef" safeAreaInsetBottom closeable :round="20">
			<view class="pop-box">
				<view class="content-pop">
					<view @click="selectaccounts('全部科目')" class="pop-inner-item" style="margin: 20rpx 0;" :style="state.accounts === '全部科目' ? 'border-color:#7175f0;color:#7175f0;background-color:#f6f7ff;' : ''">
						全部科目
					</view>
					<view class="pop-inner">
						<view v-for="item1 in state.accountsOptions" @click="selectaccounts(item1)" class="pop-inner-item"
							:style="state.accounts === item1 ? 'border-color:#7175f0;color:#7175f0;background-color:#f6f7ff;' : ''">
							{{ item1 }}
						</view>
					</view>
				</view>
			</view>
		</uv-popup>
	</view>
</template>

<script setup>
	import {
		reactive,
		ref,
		onMounted
	} from 'vue';
	import { courseListApi } from "@/api/index.js"

	const gradesRef = ref(null)
	const accountsRef = ref(null)

	const state = reactive({
		grade: "全部年级",
		accounts: "全部科目",
		courses: [],
		subject: [],
		gradOptions: [{
				title: "小学",
				content: ["一年级", "二年级", "三年级", "四年级", "五年级", "六年级"]
			},
			{
				title: "初中",
				content: ["初一", "初二", "初三"]
			},
			{
				title: "高中",
				content: ["高一", "高二", "高三"]
			}
		],
		accountsOptions: ["语文", "数学", "英语", "物理", "化学"]
	})
	
	onMounted(() => {
		getCourseList()
	})
	
	const gotoSignUp = id => {
		uni.navigateTo({
			url: `/pages/signUp/signUp?id=${id}`
		})
	}
	
	const getCourseList = async () => {
		try {
			const { data } = await courseListApi({
				grade: state.grade === "全部年级" ? "" : state.grade,
				subject: state.accounts === "全部科目" ? "" : state.accounts
			})
			state.courses = data.courses
		} catch {}
	}

	const showGradesPop = () => {
		gradesRef.value.open('bottom')
	}

	const showAccountsPop = () => {
		accountsRef.value.open('bottom')
	}
	
	const selectGrade = item => {
		state.grade = item
		gradesRef.value.close()
		getCourseList()
	}
	
	const selectaccounts = item => {
		state.accounts = item
		accountsRef.value.close()
		getCourseList()
	}
</script>

<style lang="scss" scoped>
	.container {
		background: linear-gradient(135deg, #d4d6fe 10%, #f6f7fb 90%);
		background-color: red;
		height: calc(100vh - var(--tab-bar-height));
		display: flex;
		flex-direction: column;
	}

	.content-box {
		flex: 1;
		overflow-y: auto;
		padding: 0 24rpx;
		display: flex;
		flex-direction: column;
		
		.course-list {
			margin-top: 20rpx;
			flex: 1;
			.course-box {
				display: flex;
				justify-content: space-between;
				margin-bottom: 30rpx;
				background-color: #fff;
				padding: 20rpx;
				border-radius: 20rpx;
			}
		}
	}

	.select-item {
		flex: 1;
		display: flex;
		align-items: center;
		justify-content: center;
		background-color: #fff;
		padding: 16rpx 0;
		border-radius: 9999rpx;
	}

	.pop-box {
		padding: 70rpx 20rpx;
		padding-bottom: calc(var(--tab-bar-height) + 20rpx);

		.content-pop {
			max-height: 40vh;
			min-height: 200rpx;
			overflow-y: auto;

			scrollbar-width: none;
			-ms-overflow-style: none;

			&::-webkit-scrollbar {
				display: none;
			}
		}
	}

	.pop-title {
		margin-bottom: 20rpx;
		position: relative;
		padding-left: 12rpx;

		&:before {
			content: "";
			width: 6rpx;
			height: 28rpx;
			border-radius: 3rpx;
			background-color: #ffb50f;
			position: absolute;
			top: 50%;
			left: 0;
			transform: translateY(-50%);
		}
	}

	.pop-inner {
		display: grid;
		grid-template-columns: repeat(4, 1fr);
		gap: (20rpx);
	}

	.pop-inner-item {
		font-size: 28rpx;
		border: 2rpx solid #ccc;
		text-align: center;
		padding: 10rpx 0;
		border-radius: 9999rpx;
	}
</style>