当前位置: 首页 > news >正文

开始尝试从0写一个项目--前端(四)

后台和用户分离

添加代码

src/router/index.js

{path: "/user",component: () => import("@/views/user/User.vue")},

src/views/login/Login.vue

<template><div class="login-background"><el-card class="box-card"><h2>体育器材管理后台</h2><el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-position="left" label-width="70px"class="login-from"><el-form-item label="用户名" prop="username"><el-input v-model="ruleForm.username"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input></el-form-item></el-form><div class="btnGroup"><el-button type="primary" @click="submitForm('ruleForm')" v-loading="loading">登录</el-button><el-button @click="resetForm('ruleForm')">重置</el-button></div></el-card></div>
</template><script>
// import request from '@/utils/request'
import {login} from '@/api/Student';
import {userLogin} from "@/api/User";export default {data() {return {ruleForm: {username: "",password: "",},rules: {username: [{required: true, message: "用户名不能为空!", trigger: "blur"},],password: [{required: true, message: "密码不能为空!", trigger: "blur"},],},loading: false, // 是否显示加载动画};},methods: {submitForm(formName) {// 验证表单中的账号密码是否有效,因为在上面rules中定义为了必填 required: truethis.$refs[formName].validate((valid) => {// 点击登录后,让登录按钮开始转圈圈(展示加载动画)this.loading = true;// 如果经过校验,账号密码都不为空,则发送请求到后端登录接口if (valid) {let _this = this;// 使用 axios 将登录信息发送到后端/* request({url: "/api/admin/student/login",               // 请求地址method: "post",                       // 请求方法headers: {                            // 请求头"Content-Type": "application/json",},data: {                             // 请求参数username: _this.ruleForm.username,password: _this.ruleForm.password,},}) *///封装传给请求的数据const data = {username: _this.ruleForm.username,password: _this.ruleForm.password,}if (data.username === 'admin') {login(data).then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息if (res.data.code === 1) {  // 当响应的编码为 1 时,说明登录成功sessionStorage.setItem('jwtToken', res.data.data.token); // 假设后端返回了token// 跳转页面到首页this.$router.push('/');// 显示后端响应的成功信息this.$message({message: '登录成功!',type: "success",});} else {  // 当响应的编码不为 1 时,说明登录失败// 显示后端响应的失败信息this.$message({message: res.data.msg,type: "error",});}// 不管响应成功还是失败,收到后端响应的消息后就不再让登录按钮显示加载动画了_this.loading = false;console.log(res);});} else {userLogin(data).then((res) => { // 当收到后端的响应时执行该括号内的代码,res 为响应信息,也就是后端返回的信息if (res.data.code === 1) {  // 当响应的编码为 1 时,说明登录成功sessionStorage.setItem('jwtToken', res.data.data.token); // 假设后端返回了token// 跳转页面到首页this.$router.push('/user');// 显示后端响应的成功信息this.$message({message: '登录成功!',type: "success",});} else {  // 当响应的编码不为 1 时,说明登录失败// 显示后端响应的失败信息this.$message({message: res.data.msg,type: "error",});}// 不管响应成功还是失败,收到后端响应的消息后就不再让登录按钮显示加载动画了_this.loading = false;console.log(res);});}} else {  // 如果账号或密码有一个没填,就直接提示必填,不向后端请求console.log("error submit!!");this.loading = false;return false;}});},resetForm(formName) {this.$refs[formName].resetFields();},},
};
</script><style scoped>
/* 设置登录面板居中,宽度为400px */
.box-card {margin: auto auto;width: 400px;
}/* 设置登录面板中的表单居中 */
.login-from {margin: auto auto;
}/* 背景图片 */
.login-background {background-image: url('/src/assets/bg.jpeg');background-size: cover;background-position: center;height: 100vh;display: flex;/* 如果你想要使用Flexbox来居中el-card  */justify-content: center;/* 水平居中 */align-items: center;/* 垂直居中 */
}
</style>

src/api/User.js

import request from '@/utils/request'/* 登录 */
export const userLogin = (data) =>request({'url': '/api/user/login','method': 'post',data: data})/* 退出登录 */
export const userLogOut = (params) =>request({'url': '/api/user/logout','method': 'post',params})

src/views/user

<template><div>hello!!</div>
</template><script></script>

测试

设计用户界面

src/router/index.js

//用户{path: "/user",component: () => import("@/views/home/User.vue"),redirect: "/index",children: [{path: "/index",component: () => import("@/views/user/Index.vue"),meta: {title: "用户主页面"},},{path: "/borrow",component: () => import("@/views/user/Borrow.vue"),meta: {title: "借用器材界面"},}]},

src/views/user/Index.vue

<template><div><link href="https://fonts.font.im/css?family=Pacifico" rel="stylesheet"><div class="main-title">生命在于运动</div><div class="image-container"><button @click="prevImage">&lt;</button><img :src="currentImageSource" :alt="currentAlt" class="my-img"><button @click="nextImage">&gt;</button></div><br><br><br><el-row :gutter="20" type="flex" justify="center"><el-col :span="6"><div class="grid-content bg-purple"><router-link to="/borrow">借用器材</router-link></div></el-col><el-col :span="6"><div class="grid-content bg-purple"><router-link to="/borrow">归还器材</router-link></div></el-col><el-col :span="6"><div class="grid-content bg-purple"><router-link to="/borrow">器材损坏上报</router-link></div></el-col></el-row></div>
</template><script>
import {pageEquipment} from "@/api/Equipment";export default {data() {return {currentImg: 0,imageSources: [require('@/assets/userIndex1.jpg'),require('@/assets/userIndex2.jpg'),require('@/assets/userIndex3.jpg')],intervalId: null, // 用于保存 setInterval 的 IDautoplay: true, // 控制是否自动播放name: '',        //器材名称,对应上面的输入框page: 1,         //页码pageSize: 10,    // 每页记录数total: 0,         //总记录数records: []      //当前页要展示的数据集合};},created() {this.pageQuery()},computed: {currentImageSource() {return this.imageSources[this.currentImg];},currentAlt() {return `体育运动照片 ${this.currentImg + 1}`;}},methods: {nextImage() {this.currentImg = (this.currentImg + 1) % this.imageSources.length;if (this.autoplay) {this.startAutoplay();}},prevImage() {this.currentImg = (this.currentImg - 1 + this.imageSources.length) % this.imageSources.length;if (this.autoplay) {this.startAutoplay();}},startAutoplay() {clearInterval(this.intervalId); // 清除之前的定时器this.intervalId = setInterval(() => this.nextImage(), 3000); // 每3秒切换一次图片},stopAutoplay() {clearInterval(this.intervalId);this.intervalId = null;},pageQuery() {//准备参数const params = {page: this.page,pageSize: this.pageSize,name: this.name}pageEquipment(params).then(res => {if (res.data.code === 1) {this.total = res.data.data.totalthis.records = res.data.data.records}}).catch(() => {this.$router.push("/login")})},//每页记录数发生变化时触发handleSizeChange(pageSize) {this.pageSize = pageSizethis.pageQuery()},//page发生变化时触发handleCurrentChange(page) {this.page = pagethis.pageQuery()},},mounted() {if (this.autoplay) {this.startAutoplay();}},beforeDestroy() {this.stopAutoplay(); // 组件销毁前清除定时器},
};
</script><style scoped>.main-title {font-family: 'Pacifico', cursive;font-size: 2em; /* 增大字体大小 */text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5); /* 添加文字阴影 */text-align: center; /* 居中文本 */margin-top: 1em; /* 上边距 */margin-bottom: 1em; /* 下边距 */
}.my-img {max-width: 500px; /* 设定最大宽度 */height: 250px; /* 自动调整高度,以保持长宽比 *//* 或者你可以设定具体的宽度和高度,但要注意保持长宽比 *//* width: 500px; *//* height: auto; */
}.image-container {display: flex;align-items: center;justify-content: center;}button {background-color: #f4f4f4;border: none;padding: 10px;cursor: pointer;margin: 0 10px;
}.el-row {margin-bottom: 20px;&:last-child {margin-bottom: 0;}
}.el-col {border-radius: 4px;
}.bg-purple-dark {background: #99a9bf;
}.bg-purple {background: #d3dce6;
}.bg-purple-light {background: #e5e9f2;
}.grid-content {border-radius: 4px;min-height: 36px;
}.row-bg {padding: 10px 0;background-color: #f9fafc;
}</style>

src/views/home/User.vue

<template><div class="backgroundFull"><el-container><el-header><div class="right-div"><span>设置</span><el-dropdown><i class="el-icon-setting" style="margin-left: 15px"></i><el-dropdown-menu slot="dropdown"><el-dropdown-item><el-button @click="logout" style="border: none;">修改密码</el-button></el-dropdown-item><el-dropdown-item><el-button @click="logout" style="border: none;">退出登录</el-button></el-dropdown-item></el-dropdown-menu></el-dropdown></div><div>体育器材管理系统</div></el-header><el-container><el-menu class="custom-menu-width"><el-menu-item><router-link to="/index" class="custom-link-text">主页</router-link></el-menu-item><el-menu-item><router-link to="/borrow" class="custom-link-text">借用器材</router-link></el-menu-item></el-menu><el-main><router-view/></el-main></el-container></el-container></div>
</template><script>
import { logOut } from '@/api/Student';export default {data() {return {user: {username: "",id: null,},};},methods: {logout() {// 移除本地用户登录信息sessionStorage.removeItem('userInfo');logOut().then(res => {this.$message({message: '退出成功!',}),// 跳转页面到登录页this.$router.push('/login');})}},mounted() {if (sessionStorage.getItem('userInfo')) {// 将用户信息存储到sessionStorage中this.user = JSON.parse(sessionStorage.getItem('userInfo'));}},
};
</script><style scoped>
.el-header,
.el-footer {background-color: #87ceeb;color: #333;text-align: center;line-height: 60px;/* width: 100%;height: 100px; */
}body>.el-container {margin-bottom: 40px;
}.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {line-height: 260px;
}.el-container:nth-child(7) .el-aside {line-height: 320px;
}/* 铺满整个页面 */
.backgroundFull {height: 100vh;display: flex;flex-direction: column;
}/* 靠右 */
.right-div {float: right;
}/* 靠左 */
.left-div {float: left;
}/* 导航样式 */
.custom-menu-width {width: 150px; /* 你可以根据需要调整这个宽度值 *//* 如果需要,你还可以添加其他样式,比如背景色、边框等 */background-color: #ffffff; /* 示例背景色 */border-radius: 4px; /* 示例边框圆角 */
}/* 定义一个类来修改router-link中文本的样式 */
.custom-link-text {font-size: 16px; /* 设置字体大小 */color: #000000; /* 设置文字颜色 */text-decoration: none; /* 移除下划线(如果默认有的话) *//* 可以添加更多样式,如字体家族、行高等 */
}
</style>

src/views/user/Borrow.vue


<!--借用器材-->
<template><div>这是借用器材界面</div>
</template>

测试

记得在这里修改展示的图片

未完。。。 

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 阿里云代码库 绑定git使用指引
  • 用博达网站群管理平台设计网站时如何创建二级导航
  • ​Redis 实现计数器和限速器的
  • 【AI学习】人工智能的几种主义
  • 【芯智雲城】类比半导体模拟及数模混合芯片应用和选型指导
  • 网络工程师相关认证
  • 重修设计模式-创建型-单例模式
  • SQL,连结多行的字串并去除重复
  • FreeRTOS 快速入门(四)之队列
  • 发文首选:KAN用于图像处理!效果炸裂好
  • Spring Cloud Gateway动态路由及路由插件实现方案
  • Isaac Sim仿真平台学习(2)基础知识
  • ‌前端列表展示1000条大量数据时,后端通常需要进行一定的处理。‌
  • 视频美颜SDK与直播美颜工具的架构设计与性能优化
  • STM32之点亮LED灯
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • avalon2.2的VM生成过程
  • C++入门教程(10):for 语句
  • express + mock 让前后台并行开发
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript设计模式系列一:工厂模式
  • Python 反序列化安全问题(二)
  • React Native移动开发实战-3-实现页面间的数据传递
  • Redis在Web项目中的应用与实践
  • Spring-boot 启动时碰到的错误
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 百度地图API标注+时间轴组件
  • 分布式任务队列Celery
  • 工作手记之html2canvas使用概述
  • 开源SQL-on-Hadoop系统一览
  • 聊聊hikari连接池的leakDetectionThreshold
  • 小程序 setData 学问多
  • 智能合约Solidity教程-事件和日志(一)
  • ​ ​Redis(五)主从复制:主从模式介绍、配置、拓扑(一主一从结构、一主多从结构、树形主从结构)、原理(复制过程、​​​​​​​数据同步psync)、总结
  • ​​​​​​​​​​​​​​Γ函数
  • ‌JavaScript 数据类型转换
  • ### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTr
  • #HarmonyOS:基础语法
  • #VERDI# 关于如何查看FSM状态机的方法
  • $().each和$.each的区别
  • $.ajax()
  • $NOIp2018$劝退记
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (55)MOS管专题--->(10)MOS管的封装
  • (windows2012共享文件夹和防火墙设置
  • (编译到47%失败)to be deleted
  • (力扣)1314.矩阵区域和
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (七)glDrawArry绘制
  • (四)js前端开发中设计模式之工厂方法模式
  • (五)IO流之ByteArrayInput/OutputStream
  • (小白学Java)Java简介和基本配置
  • (转)jQuery 基础
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)