uni-app 个人课程表页面

news2024/12/12 13:30:14

uni-app 个人课程表页面

插件参考地址
大部分代码都是参考了上述代码,只对代码做出了优化

1. 页面模板

schedule.vue 文件中,编写页面结构:

<template>
	<view>
		<u-navbar title="个人中心">
			<view class="u-nav-slot" slot="left">
				<u-icon name="arrow-left" size="19" @click="back"></u-icon>
			</view>
			<view class="u-nav-slot" slot="center">
				<picker class="week" style="height: 100%;" @change="onPickerChange" :value="currentWeek-1" :range="weekOptions">
					<view>
						<text style="color: #d3dbff">第{{ currentWeek }}周</text>
						<uni-icons type="down" size="20" style="margin-left: 10rpx;" :color="themeColor"></uni-icons>
					</view>
				</picker>
			</view>
			<view class="u-nav-slot" slot="right">
				<u-icon name="settings" size="19"></u-icon>
			</view>
		</u-navbar>

		<!-- 日期列表 -->
		<view style="display: flex; flex-direction: row; margin-top: 60px">
			<view style="font-size: 18px; width: 35px; text-align: center; display: flex; justify-content: center; align-items: center; font-weight: 600; color: #d3dbff">
				{{ currentMonth }}
			</view>
			<view class="day">
				<view v-for="(day, index) in dayList" :key="index" class="day-text">
					<view style="margin-top: 5px; color: #909399">周{{ day.day }}</view>
					<view style="margin-top: 2.5px; color: #909399; font-size: 10px;">{{ day.date }}</view>
				</view>
			</view>
		</view>

		<!-- 课程滚动区域 -->
		<view class="scroll">
			<view style="width: 750rpx; display: flex;">
				<view style="color: #d3dbff">
					<view v-for="(pitch, index) in pitchNumbers" :key="index" class="left">
						<view style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
							<view>{{ pitch }}</view>
							<view style="color: #909399; font-size: 10px;">
								<view>{{ timeMap[pitch - 1].start }}</view>
								<view>{{ timeMap[pitch - 1].end }}</view>
							</view>
						</view>
					</view>
				</view>
				<view v-for="(pitch, index) in pitchNumbers" :key="index">
					<view :style="{
						width: '750rpx',
						marginTop: (index + 1) * 120 + 'rpx',
						position: 'absolute',
						borderBottom: '1px solid rgba(200, 200, 200, 0.1)',
						left: '0'
					}"></view>
				</view>
				<view style="width: calc(100% - 70rpx); position: relative;">
					<view v-for="(item, index) in currentSchedule" :key="index" @click="openDetail(item)">
						<view class="flex-item class-item" :style="{
							marginRight: '5rpx',
							marginLeft: `calc((${item.day - 1}) * 100% / 7 + 5rpx)`,
							marginTop: ((item.startPeriod - 1) * 60 + 2.5) * 2 + 'rpx',
							marginBottom: '5rpx',
							height: (((item.endPeriod - item.startPeriod + 1)) * 60 - 5) * 2 + 'rpx',
							backgroundColor: colorArray[((item.endPeriod + item.day) * item.name.length) % 7]
						}">
							<view class="text">
								<view style="padding-left: 4rpx; margin-right: 4rpx;">
									{{ formatClassText(item) }} @{{ item.room }} @{{ item.attendance }}
								</view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>

		<!-- 弹出层 -->
		<uni-popup ref="popup" background-color="none">
			<view class="context">
				<view class="info">
					<view style="padding: 10rpx 20rpx;">
						<view class="name" style="color: #303133; font-size: 18px; font-weight: bold;">
							{{ selected.name }}
						</view>
						<view class="less">
							<view class="item">
								<uni-icons type="calendar" size="20"></uni-icons>
								<text class="label">节次:</text> <text class="value">{{ selected.startPeriod }}-{{ selected.endPeriod }}节</text>
							</view>
							<view class="item">
								<uni-icons type="auth-filled" size="20"></uni-icons>
								<text class="label">老师:</text> <text class="value">{{ selected.teacher }}</text>
							</view>
							<view class="item">
								<uni-icons type="flag" size="20"></uni-icons>
								<text class="label">教室:</text> <text class="value">{{ selected.room }}</text>
							</view>
						</view>
					</view>
				</view>
			</view>
		</uni-popup>
	</view>
</template>

3. 页面逻辑

script 部分实现页面的逻辑:

<script>
import dayjs from 'dayjs';

export default {
	data() {
		return {
			themeColor: "#d3dbff",
			currentWeek: 1,
			statusBarHeight: 0,
			topHeight: 0,
			weekOptions: ['第一周', '第二周', '第三周', '第四周', '第五周', '第六周', '第七周', '第八周', '第九周', '第十周', '第十一周', '第十二周', '第十三周', '第十四周', '第十五周', '第十六周', '第十七周', '第十八周'],
			dayList: [],
			currentMonth: "",
			startingDate: { y: 2024, m: 9, d: 10 },
			timeMap: [
				{ start: '8:00', end: '8:45' },
				{ start: '8:55', end: '9:40' },
				{ start: '10:00', end: '10:45' },
				{ start: '10:55', end: '11:40' },
				{ start: '14:20', end: '15:15' },
				{ start: '15:25', end: '16:10' },
				{ start: '16:30', end: '17:15' },
				{ start: '17:25', end: '18:10' },
				{ start: '19:00', end: '19:45' },
				{ start: '19:55', end: '20:40' },
				{ start: '20:50', end: '21:35' },
				{ start: '20:45', end: '21:20' }
			],
			currentSchedule: [ /* 课程安排数据 */ ],
			pitchNumbers: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
			colorArray: ['#ff55ff', '#00aaff', '#aa5500', '#00aa00', '#aaaaff', '#da786b', '#5297f6', '#aa007f', '#7ac077', '#6ec8bf'],
			selected: { name: '', teacher: '', room: '' }
		}
	},
	onLoad() {
		this.calculateDayInfo();
		this.calculateCurrentWeek();
	},
	methods: {
		calculateDayInfo() {
			// 计算当前周的日期信息
			const dayArray = [7, 1, 2, 3, 4, 5, 6];
				const today = new Date();
				const currentMonth = today.getMonth() + 1; // 当前月份(1-12)
				this.currentMonth = this.formatNumber(currentMonth, 2); // 格式化月份为两位数

				const currentDay = today.getDate(); // 当前日期(1-31)
				const currentTime = today.getTime();
				const weekDay = dayArray[today.getDay()]; // 获取当前星期几(1-7)

				const oneDayTime = 24 * 60 * 60 * 1000; // 一天的毫秒数
				const mondayTime = currentTime - (weekDay - 1) * oneDayTime; // 获取上一个星期一的时间

				const dates = [];
				for (let i = 0; i < 7; i++) {
					const date = dayjs(mondayTime).add(i, 'day');
					dates.push({
						day: this.getDayName(i),
						date: `${this.formatNumber(date.month() + 1, 2)}/${this.formatNumber(date.date(), 2)}`
					});
				}
				this.dayList = dates; // 更新日期列表
		},
		calculateCurrentWeek() {
			// 计算当前周数
			const today = new Date();
				const currentYear = today.getFullYear();
				const currentMonth = today.getMonth() + 1;
				const currentDate = today.getDate();

				this.currentWeek = this.calculateWeekNumber(this.startingDate.y, this.startingDate.m, this.startingDate.d,
					currentYear, currentMonth, currentDate);
		},
		// 计算周数的辅助函数
			calculateWeekNumber(startYear, startMonth, startDay, currentYear, currentMonth, currentDay) {
				const dayArray = [1, 2, 3, 4, 5, 6, 0]; // 将星期几转为数组
				const startDate = new Date(startYear, startMonth - 1, startDay); // 初始化开始日期
				const endDate = new Date(currentYear, currentMonth - 1, currentDay); // 初始化结束日期

				const startDayOfWeek = startDate.getDay(); // 获取开始日期是星期几
				const adjustedStartDay = dayArray.indexOf(startDayOfWeek); // 将星期几转换为 1-7

				const endDayOfWeek = endDate.getDay();
				const adjustedEndDay = dayArray.indexOf(endDayOfWeek);

				const daysUntilEnd = 7 - adjustedEndDay; // 计算结束日期到下一个星期一的天数
				const adjustedStartDate = new Date(startYear, startMonth - 1, startDay - adjustedStartDay); // 调整开始日期到本周一
				const adjustedEndDate = new Date(currentYear, currentMonth - 1, currentDay + daysUntilEnd); // 调整结束日期到下周一

				const startTime = adjustedStartDate.getTime();
				const endTime = adjustedEndDate.getTime();

				// 当前时间 - 开始时间 = 当前周数
				const weekNumber = (Math.abs(endTime - startTime) / 1000 / 60 / 60 / 24 / 7);
				return weekNumber;
			},
		onPickerChange(event) {
			// 处理选择周次的变化
			const selectedWeekIndex = parseInt(event.detail.value); // 选择的周次索引
				this.currentWeek = selectedWeekIndex + 1; // 更新当前周数
				
				// 将 startingDate 对象转换为 dayjs 日期
				const startingDate = dayjs(`${this.startingDate.y}-${this.startingDate.m}-${this.startingDate.d}`);
				if (!startingDate.isValid()) {
					console.error("Invalid starting date");
					return; // 如果日期无效,则退出
				}

				// 计算当前周的开始日期(周一)
				const weekDifference = this.currentWeek - 1; // 当前周与起始周的差
				const mondayTime = startingDate.add(weekDifference, 'week').startOf('week'); // 获取当前周的周一

				// 更新 currentMonth
				this.currentMonth = mondayTime.month() + 1; // month() 返回的是 0-11,所以加 1

				const dates = [];
				for (let i = 0; i < 7; i++) {
					const dayTime = mondayTime.add(i, 'day'); // 获取当前周的每一天
					dates.push({
						day: this.getDayName(i), // 获取星期名称
						date: `${this.formatNumber(dayTime.month() + 1, 2)}/${this.formatNumber(dayTime.date(), 2)}` // 格式化日期
					});
				}
				this.dayList = dates; // 更新日期列表
				console.log(this.dayList); // 检查更新的日期列表
		},
		formatClassText(item) {
			// 格式化课程文本
			return ('' + num).length < length ? ((new Array(length + 1)).join('0') + num).slice(-length) : '' + num;
		},
		// 获取星期名称
			getDayName(index) {
				const days = ['一', '二', '三', '四', '五', '六', '日'];
				return days[index];
			},
		openDetail(item) {
			this.selected = item;
			this.$refs.popup.open('center');
		},
		back() {
			uni.navigateBack();
		}
	}
}
</script>

4. 样式设计

schedule.scss 文件中添加样式:

.top {
	position: relative;
	width: 750rpx;
	background-color: #fff;

	.container {
		display: flex;
		justify-content: space-between;
		align-items: center;
		width: 100%;
	}

	.left {
		margin-right: auto;
		text-align: left;
	}

	.center {
		flex: 1;
		text-align: center;
	}

	.right {
		text-align: right;
	}
}

.day {
	display: flex;
	height: 70rpx;
	flex-direction: row;
}

.day-text {
	width: calc((750rpx - 70rpx) / 7);
	height: 62rpx;
	font-weight: 600;
	font-size: 26rpx;
	justify-content: center;
	flex-direction: column;
	display: flex;
	align-items: center;
}

.scroll {
	height: 1170rpx;
	z-index: 101;
}

.left {
	width: 70rpx;
	height: 120rpx;
	font-size: 26rpx;
	justify-content: center;
	display: flex;
	align-items: center;
}

.class-item {
	width: calc(100% / 7 - 10rpx);
	position: absolute;
	box-sizing: border-box;
	display: flex;
	border-radius: 16rpx;
	font-size: 20rpx;
	color: #ffffff;
	overflow: hidden;
}

.text {
	width: calc(680rpx / 7 - 10rpx);
	padding-top: 10rpx;
}

.context {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	padding: 15rpx;
	height: auto;
	width: 750rpx;

	.info {
		position: relative;
		width: 562rpx;
		height: auto;
		background-color: #fff;
		border-radius: 4px;
		padding: 15rpx;
		box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
	}

	.name {
		color: #303133;
		font-size: 18px;
		font-weight: bold;
		margin-bottom: 10rpx;
	}

	.item {
		width: 100%;
		height: 40rpx;
		display: flex;
		margin-left: 20rpx;
		justify-content: flex-start;
		align-items: center;
	}

	.label {
		font-size: 16px;
		color: #606266;
	}

	.value {
		color: #aeb0b4;
	}
}

5. 运行

完成上述步骤后,您可以在开发工具中运行项目,查看个人课程表页面的效果。确保所有功能正常,如周次选择、课程详情弹出层等。

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2258260.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ElementEye,网页分析器

介绍 我们经常使用Python写爬虫&#xff0c;爬到网页数据之后&#xff0c;就需要用beautifulSoup进行解析。因为写爬虫并不是我的主营工作&#xff0c;大多数只是用来分析一下想要的数据而已&#xff0c;所以经常会忘记beautifulSoup的用法。 同时&#xff0c;我们总是分析页面…

【Compose multiplatform教程】01 创建你的多平台项目 <官网搬运>

这是 “创建带有共享逻辑和用户界面的 Compose 多平台应用” 教程的第一部分。 第一步&#xff1a;创建你的多平台项目 第二步&#xff1a;探究可组合代码 第三步&#xff1a;修改项目 第四步&#xff1a;创建你自己的应用程序 在这里&#xff0c;你将学习如何使用 Kotlin 多平…

使用OpenTK展示3D点云图像(C#)

最近在研究3D显示&#xff0c;找到一款在winform上展示3D点云的控件&#xff0c;并且实现了点线面的展示&#xff0c;及光照渲染纹理贴图等功能&#xff0c;如下面几张图所展示。 一些基础知识可以在LearnOpenTK - OpenTK 这个网站上学习到。 我这边使用的是openTK3.3.3版本&a…

李宏毅机器学习-批次 (batch)和动量(momentum)

一.batch&#xff08;批次&#xff09; 在计算微分时&#xff0c;不是对所有的数据算出来的Loss值做微分&#xff0c;而是将所有的数据分成一个一个的batch。一个batch是一个B&#xff0c;在更新参数时&#xff0c;拿B的资料计算Loss&#xff0c;计算gradient&#xff0c;再更新…

洗鞋小程序(源码+文档+部署+讲解)

本文将深入解析“洗鞋小程序”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 为洗鞋提供服务&#xff0c;包含小程序和管理端。 本项目名称为洗鞋小程序&#xff0c;是一个基于小程序的在线洗鞋平台。该系统提供下单、订单管…

【数据结构】二叉树的性质和存储结构

性质 在二叉树的第i层上至多有2^{i-1}个结点,至少有1个结点 深度为k的二叉树至多有2^{k-1}个结点&#xff08;k≥1&#xff09;&#xff0c;至少有k个结点 对任何一棵二叉树T&#xff0c;如果其叶子数为n0&#xff0c;度为2的结点数为n2&#xff0c;则n0n21 具有n个结点的完…

交换排序(Swap Sort)详解

交换排序Swap Sort详解 冒泡排序冒泡算法代码实现冒泡分析 快速排序快排算法代码实现快排分析 交换类排序主要是通过两两比较待排元素的关键字&#xff0c;若发现与排序要求相逆&#xff0c;则交换之。在这类排序方法中最常见的是起泡排序&#xff08;冒泡排序&#xff09;和快…

MySQL追梦旅途之性能优化

1、索引优化 索引可以显著加速查询操作&#xff0c;但过多或不适当的索引也会带来负面影响&#xff08;如增加写入开销&#xff09;。因此&#xff0c;选择合适的索引至关重要。 创建索引&#xff1a; 为经常用于WHERE子句、JOIN条件和ORDER BY排序的列创建索引。 CREATE I…

小程序IOS安全区域优化:safe-area-inset-bottom

ios下边有一个小黑线&#xff0c;位于底部的元素会被黑线阻挡 safe-area-inset-bottom 一 用法及作用&#xff1a; IOS全面屏底部有小黑线&#xff0c;位于底部的元素会被黑线阻挡&#xff0c;可以使用以下样式&#xff1a; .model{padding-bottom: constant(safe-area-ins…

矩阵的乘(包括乘方)和除

矩阵的乘分为两种&#xff1a; 一种是高等代数中对矩阵的乘的定义&#xff1a;可以去这里看看包含矩阵的乘。总的来说&#xff0c;若矩阵 A s ∗ n A_{s*n} As∗n​列数和矩阵 B n ∗ t B_{n*t} Bn∗t​的行数相等&#xff0c;则 A A A和 B B B可相乘&#xff0c;得到一个矩阵 …

解决阿里云轻量级服务器 Ubuntu 24.04.1 LTS 没网也 ping 不通 8.8.8.8 以及 route -n 没有输出任何转发信息

事情发生在两天前&#xff0c;位于公网的阿里云轻量级服务器&#xff08;Ubuntu 24.04.1 LTS&#xff09;忽然没网。主要是上次上服务器进行配置已经是一个多月前&#xff0c;最近也没有做什么事情&#xff0c;就忽然没网了&#xff0c;让人纳闷。更主要的是&#xff0c;上次备…

Cesium中实现仿ArcGIS三维的动态图层加载方式

Cesium 加载 ArcGIS 动态图层的方式 如果你在 Cesium 中加载过 ArcGIS 的动态图层&#xff0c;你会发现&#xff0c;Cesium 对于动态图层仍然采用类似切片图层的逻辑进行加载。也就是每个固定的瓦片 export 一张图片。 这样会造成一些问题&#xff1a; 请求量大&#xff0c;…

Tablesaw封装Plot.ly实现数据可视化

上文介绍tablesaw的数据处理功能&#xff0c;本文向你展示其数据可视化功能&#xff0c;并通过几个常用图表示例进行说明。 Plot.ly包装 可视化是数据分析的重要组成部分&#xff0c;无论你只是“查看”新数据集还是验证机器学习算法的结果。Tablesaw是一个开源、高性能的Java…

智慧商城项目2(vue核心技术与实战)

页面访问拦截了解 router/index.js import Vue from vue import VueRouter from vue-router import Login from /views/login import Layout from /views/layout import Search from /views/search import SearchList from /views/search/list import Prodetail from /views/…

第一个C++程序--(蓝桥杯备考版)

第一个C程序 基础程序 #include <iostream>//头⽂件 using namespace std;//使⽤std的名字空间 int main()//main函数 {cout << "hello world!" << endl; //输出&#xff1a;在屏幕打印"hello world!" return 0;}main函数 main 函数是…

华为云域名网站,域名切换到Cloudflare CDN出现访问报错:DNS 重定向次过多

网站域名切换到Cloudflare出现访问报错&#xff1a;重定向次过多&#xff0c;应该如何处理&#xff1f; 最近我自己已经遇到很多次这个情况了&#xff0c;将网站域名DNS切换到Cloudflare之后&#xff0c;网站会打不开&#xff0c;出现重定向次数过多报错。 网站域名切换到Clo…

颜色的基本处理

数码相机能够获取彩色图像&#xff0c;但相机的色彩处理是一个非常复杂的过程&#xff0c;是非常重要的。 此过程生产制造商在细节方面都是不公布的&#xff0c;但是基本的概念是相同的。当相机捕捉一个真实场景时&#xff0c;是怎么还原成人眼所看到的图像呢&#xff1f; 1.R…

与 Cursor AI 对话编程:2小时开发报修维修微信小程序

本文记录了如何通过与 Cursor AI 对话&#xff0c;全程不写一行代码的情况下&#xff0c;完成一个完整的报修小程序。整个过程展示了 AI 如何帮助我们&#xff1a; 生成代码 、解决问题、优化实现、完善细节。 先看一下效果图&#xff1a; 一、项目配置 首先我是这样和 AI 对…

System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本

问题1&#xff1a;“/”应用程序中的服务器错误。 System.Data.OracleClient 需要 Oracle 客户端软件 version 8.1.7 或更高版本。 说明: 执行当前 Web 请求期间&#xff0c;出现未经处理的异常。请检查堆栈跟踪信息&#xff0c;以了解有关该错误以及代码中导致错误的出处的详细…

leetcode909:蛇梯棋

给你一个大小为 n x n 的整数矩阵 board &#xff0c;方格按从 1 到 n2 编号&#xff0c;编号遵循 转行交替方式 &#xff0c;从左下角开始 &#xff08;即&#xff0c;从 board[n - 1][0] 开始&#xff09;的每一行改变方向。 你一开始位于棋盘上的方格 1。每一回合&#xf…