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

微服务项目->在线oj系统(Java-Spring)----[前端]

前端开发

创建一个VUE项目

这个时候,我们存放文件的地方就会出现一个文件夹

然后我们在vscode上的工作区中打开即可(方便编写代码)

删除并修改vue代码

这里我们需要删除我们不需要的代码和样式

这里是初始的代码格式

修改之后代码结构

Login.vue代码

主要是样式和布局,这个我们后端不做深入

<template><div class="login-page"><div class="orange"> </div><div class="blue"></div><div class="blue small"></div><div class="login-box"><div class="logo-box"><div class="right"><div class="sys-name">⽐特OJ后台管理</div><div class="sys-sub-name">帮助100万学⽣就业</div></div></div><div class="form-box"><div class="form-item"><img src="../assets/images/shouji.png"><el-input v-model="userAccount" placeholder="请输⼊账号" /></div><div class="form-item"><img src="../assets/images/yanzhengma.png"><el-input v-model="password" type="password" show-password placeholder="请输⼊密码" /></div><div class="submit-box" @click="login">登录</div></div></div></div>
</template>
<script setup>
import { ref } from 'vue'
import { loginServeice } from '@/apis/suer'
// 假设 request 封装在 @/utils/request.js 中,根据实际路径调整
import request from '@/utils/request';
import router from '@/router' // 假设路由文件在 src/router/index.js
const userAccount = ref('')
const password = ref('')
import { setToken } from '@/utils/cookie'
async function login() {try {const loginresult = await loginServeice(userAccount.value, password.value)console.log(loginresult)setToken(loginresult.data)router.push('/oj/system')} catch (error) {console.error('登录失败:', error);}
}
</script>
<style lang="scss" scoped>
.login-page {width: 100vw;height: 100vh;position: relative;overflow: hidden;.login-box {overflow: hidden;.logo-box {display: flex;align-items: center;margin-bottom: 30px;img {width: 68px;height: 68px;margin-right: 16px;}.sys-name {height: 33px;font-family: PingFangSC, PingFang SC;font-weight: 600;font-size: 24px;color: #222222;line-height: 33px;margin-bottom: 13px;}.sys-sub-name {height: 22px;font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 16px;color: #222222;line-height: 22px;}}:deep(.form-box) {.submit-box {margin-top: 90px;width: 456px;height: 48px;background: #32C5FF;border-radius: 8px;cursor: pointer;display: flex;justify-content: center;align-items: center;font-family: PingFangSC, PingFang SC;font-weight: 600;font-size: 16px;color: #FFFFFF;letter-spacing: 1px;}.form-item {display: flex;align-items: center;width: 456px;height: 48px;background: #F8F8F8;border-radius: 8px;margin-bottom: 30px;position: relative;.code-btn-box {position: absolute;right: 0;width: 151px;height: 48px;background: #32C5FF;border-radius: 8px;top: 0;display: flex;align-items: center;justify-content: center;cursor: pointer;span {font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 16px;color: #FFFFFF;}}.error-tip {position: absolute;width: 140px;text-align: right;padding-right: 12px;height: 20px;font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 14px;color: #FD4C40;line-height: 20px;right: 0;&.bottom {right: 157px;}}.el-input {width: 380px;font-family: PingFangSC, PingFang SC;font-weight: 400;font-size: 16px;color: #222222;}.el-input__wrapper {border: none;box-shadow: none;background: transparent;width: 230px;padding-left: 0;}img {width: 24px;height: 24px;margin: 0 18px;}}}width:456px;height:404px;background: #FFFFFF;box-shadow: 0px 0px 6px 0px rgba(0, 0, 0, 0.1);border-radius: 10px;opacity: 0.9;position: absolute;top: 50%;left: 50%;transform: translate(-50%, -50%);z-index: 2;padding: 0 72px;padding-top: 50px;}&::after {position: absolute;top: 0;left: 0;height: 100vh;bottom: 0;right: 0;background: rgba(255, 255, 255, .8);z-index: 1;content: '';}.orange {background: #F0714A;width: 498px;height: 498px;border-radius: 50%;background: #F0714A;opacity: 0.67;filter: blur(50px);left: 14.2%;top: 41%;position: absolute;}.blue {width: 334px;height: 334px;background: #32C5FF;opacity: 0.67;filter: blur(50px);left: 14.2%;top: 42%;position: absolute;top: 16.3%;left: 80.7%;&.small {width: 186px;height: 186px;top: 8.2%;left: 58.2%;}}
}
</style>
修改router⽬录下index.js⽂件
主要功能是路由功能
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes: [{path: '/oj/login',name: 'login',component: () => import('../views/Login.vue'),},],
})export default router

Element-plus

先导⼊包:
 npm install element-plus --save

按需导⼊
npm install -D unplugin-vue-components unplugin-auto-import

加入配置

修改账户和密码框

  • v-model:前端与Vue实例的双向绑定

在一个简单的登录页面,需要获取用户输入的用户名。可以在<input>标签上使用v-model,将它绑定到 Vue 实例中的一个数据属性上

  • type="password",设置格式为密码框
  • show-password,设置可显示密码

Axios

发起 HTTP 请求

作用:
  • 向后端 API 获取数据
  • 提交数据到后端
安装Axios
npm install axios
创建实例
import axios from "axios"; const service = axios.create({baseURL: 127.0.0.1:19090/systemtimeout: 5000, 
});export default service;

127.0.0.1:19090/system是所以使用它的前缀,注意要加上http,否则会自动加上我们vue的前缀127.0.0.1:5173

这是是为进行跨域访问所以进行优化


import axios from "axios"; const service = axios.create({baseURL: "/dev-api",timeout: 5000, 
});

因为浏览器不同域不可访问, 添加代理

这里的意思将请求转发到127.0.0.1:19090/system/dev-api/sysUser/login,然后将/dev-api/替换为空

定义请求⽅法:
创建apis⽬录
定义登录⽅法
import service from "@/utils/request";
import request from '@/utils/request';
export function loginServeice(userAccount, password) {return request({url: "/sysUser/login",method: "post",data: { userAccount, password },});
}

发送token

安装js-cookie
npm install js-cookie
创建cookie.js
import Cookies from "js-cookie";
const TokenKey = "Admin-Oj-b-Token";
export function getToken() {return Cookies.get(TokenKey);
}
export function setToken(token) {return Cookies.set(TokenKey, token);
}export function removeToken() {return Cookies.remove(TokenKey);
}

响应拦截

我们之前的代码太过于冗余,需要res.data.data,这样不利于我们操作,所以来一个响应拦截

service.interceptors.response.use((res) => {// 未设置状态码则默认成功状态const code = res.data.code;const msg = res.data.msg;if (code !== 1000) {ElMessage.error(msg);return Promise.reject(new Error(msg));} else {return Promise.resolve(res.data);}},(error) => {return Promise.reject(error);}
);

这里的error是指请求失效,而不是密码错误等错误

我们这里的return Promise.reject(new Error(msg));会抛出异常,就需要我们下面代码中捕获异常,然后对异常情况(密码错误或者账号不存在)进行处理,

ElMessage.error(msg); 是使用Elment*进行的错误提示

修改Login.vue代码

import { ref } from 'vue'
import { loginServeice } from '@/apis/suer'
// 假设 request 封装在 @/utils/request.js 中,根据实际路径调整
import request from '@/utils/request';
import router from '@/router' // 假设路由文件在 src/router/index.js
const userAccount = ref('')
const password = ref('')
import { setToken } from '@/utils/cookie'
async function login() {try {const loginresult = await loginServeice(userAccount.value, password.value)console.log(loginresult)setToken(loginresult.data)router.push('/oj/system')} catch (error) {console.error('登录失败:', error);}
}

router.push('/oj/system')可以跳转带另一个页面

setToken来设置我们的token

http://www.dtcms.com/a/409818.html

相关文章:

  • 做网站撘框架小米手机如何做游戏视频网站
  • 如何建自己网站做淘宝客黄骅港吧
  • 交叉口内CAV调度:轨迹优化与目标速度规划,助力智能交通无缝运行!
  • Navicat 技术指引 | KingbaseES 专用 AI 助手
  • 如何优化Android app耗电量
  • 面试复习题---Flutter 资深专家
  • 在 C# 中将邮件转换为 PDF | MSG 转 PDF | EML 转 PDF
  • 【LangChain4j+Redis】会话记忆功能实现
  • Android Handler的runWithScissors方法
  • 180课时吃透Go语言游戏后端开发3:Go语言中其他常用的数据类型
  • 在 Android 11 上实现 WiFi 热点并发支持(同时开启 STA + AP 模式)
  • 济南高新区网站建设wordpress举报插件
  • html 占位符
  • GPT-5 Codex正式上线 Azure AI Foundry(国际版)
  • C++设计模式之结构型模式:享元模式(Flyweight)
  • STM32 智能垃圾桶项目笔记(一):超声波模块(HC-SR04)原理与驱动实现
  • 全文 -- Vortex: Extending the RISC-V ISA for GPGPU and 3D-Graphics Research
  • 设计网站推荐理由公司网站备案电话
  • 事件驱动与CDS:基于FHIR R5 Subscriptions与Bulk Data的再考察(下)
  • Tigshop开源商城系统 Java v5.2.2 / PHP v5.1.6版本正式发布(ES搜索上新)
  • 仙游县住房和城乡建设局网站1元涨1000粉丝网站
  • 【Linux】进程概念(六):进程地址空间深度解析:虚拟地址与内存管理的奥秘
  • 网站怎么做微信登录界面wordpress restful
  • Linux下写一个简陋的shell程序
  • OpenSource - 异构数据库数据与结构同步工具dbswitch
  • 首次披露潮玩成长性,量子之歌敲响新财年重估的钟声
  • jdk21 list中筛选出符合条件的list
  • Session共享问题
  • 3. Ollama 安装,流式输出,多模态,思考模型
  • Go基础:常用数学函数处理(主要是math包rand包的处理)