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

Tlias案例-登录 退出 打包部署

登录

步骤:
1:为“登录”按钮绑定事件,点击登录按钮,发送异步请求到服务器端,执行登录操作。

2:为“取消”按钮绑定事件,点击取消按钮,清空登录表单数据。

基本功能

<script setup>import { ref } from 'vue'import { loginApi } from '@/api/login'import { ElMessage } from 'element-plus'import { useRouter } from 'vue-router'let loginForm = ref({username:'', password:''})const router = useRouter();//登录const login = async () => {let result = await loginApi(loginForm.value); if(result.code){ElMessage.success('登录成功');// 页面跳转  router.push('/index');}else{ // 失败ElMessage.error(result.msg);}}//重置const reset = () => {loginForm.value = {username:'', password:''}}</script><template><div id="container"><div class="login-form"><el-form label-width="80px"><p class="title">Tlias智能学习辅助系统</p><el-form-item label="用户名" prop="username"><el-input v-model="loginForm.username" placeholder="请输入用户名"></el-input></el-form-item><el-form-item label="密码" prop="password"><el-input type="password" v-model="loginForm.password" placeholder="请输入密码"></el-input></el-form-item><el-form-item><el-button class="button" type="primary" @click="login">登 录</el-button><el-button class="button" type="info" @click="reset">重 置</el-button></el-form-item></el-form></div></div>
</template><style scoped>
#container {padding: 10%;height: 410px;background-image: url('../../assets/bg1.jpg');background-repeat: no-repeat;background-size: cover;
}.login-form {max-width: 400px;padding: 30px;margin: 0 auto;border: 1px solid #e0e0e0;border-radius: 10px;box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);background-color: white;
}.title {font-size: 30px;font-family: '楷体';text-align: center;margin-bottom: 30px;font-weight: bold;
}.button {margin-top: 30px;width: 120px;
}
</style>
import request from "@/utils/request";//登录
export const loginApi = (data) => request.post('/login', data);

 

问题:目前执行登录操作,登录成功之后,并没有将令牌信息存储起来,在后续的每次操作中,也就拿不到登录时的令牌信息了。

方案:需要在登录成功后,将令牌信息存储起来。在后续的请求中,再将令牌取出来,携带到服务器。

这里使用 localStorage 来进行存储,下面介绍一下这个东西。

localStorage 是浏览器提供的本地存储机制(5 MB)。

存储形式为 key - value 形式,键和值都是字符串类型。

API 方法:

 

  //登录const login = async () => {let result = await loginApi(loginForm.value); if(result.code){ElMessage.success('登录成功');//存储当前登录的用户信息localStorage.setItem('user',JSON.stringify(result.data));// 页面跳转router.push('/index');}else{ // 失败ElMessage.error(result.msg);}}

携带令牌访问服务器端

在后续的每一次 Ajax 请求中都获取 localStorage 中的令牌,在请求头中将令牌携带到服务器端。

如果我们要用 localStroage 的话,需要在后续的每一次 Ajax 请求中都要获取 localStorage 中的令牌,然后在请求头中将令牌携带到服务端。但是这个过程过于繁琐了 ,我们考虑 axios 拦截器

其中包含了 request 拦截器,和 response 拦截器,后者我们在一开始就实现了,现在要实现前者 

import axios from 'axios'//创建axios实例对象
const request = axios.create({baseURL: '/api',timeout: 600000
})//axios的请求 request 拦截器 - 获取 localStorage 中保存的 token,在请求头中增加 token 请求头
request.interceptors.request.use((config) => { //成功回调const loginUser = JSON.parse(localStorage.getItem('user'));if(loginUser && loginUser.token){config.headers.token = loginUser.token;}return config},(error) => { //失败回调return Promise.reject(error)}
)//axios的响应 response 拦截器
request.interceptors.response.use((response) => { //成功回调return response.data},(error) => { //失败回调return Promise.reject(error)}
)export default request

 这里有一个例外,那就是文件上传这个接口,我们文件上传时,并没有基于 axios 实例(request)来发送请求,我们用的是 “饿了么” 里面的组件发送的请求,我们直接参考 “饿了么”官方文档。这里添加一个 header 就可以

      <!-- 第五行 --><el-row :gutter="20"><el-col :span="24"><el-form-item label="头像"><el-uploadclass="avatar-uploader"action="/api/upload":headers="{'token': token}":show-file-list="false":on-success="handleAvatarSuccess":before-upload="beforeAvatarUpload"><img v-if="employee.image" :src="employee.image" class="avatar" /><el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon></el-upload></el-form-item></el-col>
const token = ref('')//钩子函数
onMounted(() => {search(); //查询员工列表数据queryAllDepts();//查询所有部门列表数据getToken();
})//获取请求头
const getToken = () => {const loginUser = JSON.parse(localStorage.getItem('user'));if(loginUser && loginUser.token){token.value = loginUser.token;}
}

 响应401跳转登录界面

这里还有一个 bug 就是当服务器端给前端响应的状态码是 401(未登录 或 未认证) 时,前端不会跳转到登录界面。

那么既然是后端响应的 401 我们自然要在响应拦截器里进行操作

import router from '../router'
import { ElMessage } from 'element-plus'//axios的响应 response 拦截器
request.interceptors.response.use((response) => { //成功回调return response.data},(error) => { //失败回调if(error.response.status === 401){ // 三个等号是全等(比较类型和值)ElMessage.error('登录信息已过期,请重新登录');router.push('/login');}else{ElMessage.error('接口出错,请稍后再试');}return Promise.reject(error)}
)

 

退出

 分两步

1:展示当前登录的员工的姓名。

2:删除登录信息。

先完成第一步

<script setup>
import { ref, onMounted } from 'vue'const empName = ref('');onMounted(() => {empName.value = JSON.parse(localStorage.getItem('user')).name;
})</script>
          <a href="javascript:void(0);" @click="logout"><el-icon><SwitchButton /></el-icon> 退出登录[{{ empName }}]</a>

然后是第二步,完成这个 logout 方法

const logout = () => {//弹出确认框ElMessageBox.confirm('您确认退出登录吗?','提示',{ confirmButtonText: '确认',cancelButtonText: '取消',type: 'warning'}).then(async () => { //确认ElMessage.success('退出登录成功');//清除本地存储localStorage.removeItem('user');// 页面跳转router.push('/login');}).catch(() => { //取消ElMessage.info('您已取消退出登录');})
}

打包

 

打包后会出现这个 dist 目录

 

 

 部署

部署在 Nginx 服务器。

介绍:Nginx 是一款轻量级的 Web 服务器/反向代理服务器及电子邮件(IMAP/P0P3)服务器。其特点是占有内存少,并发能力强,在各大互联网公司都有非常广泛的使用。

官网:https://nginx.org/

下载完成之后的步骤:

1:部署:将打包好的 dist 目录下的文件,复制到 nginx 安装目录的 html 目录下。(注意不要复制 dist 目录,复制的是 dist 目录里的文件

2:启动:双击 nginx.exe 文件即可,Nginx 服务器默认占用 80 端口号。

 

完成了上述两个步骤后,会发现还是连接不到服务器,那是因为在打包时并没有将 vite.config.js 这个配置文件打包进去,所以无法连接到服务器,这时用 nginx 当中的反向代理就可以解决这个问题

用我们需要的 nginx.conf 文件替换掉 原本 conf 目录下的该文件

 最后我们要在 nginx 安装目录下执行以下命令,代表重新加载 nginx 的配置文件

 

如果我们要停止

最后一点注意事项:
Nginx 默认占用的端口号是 80 端口号,如果 80 端口号被占用,可以在 nginx.conf 中修改端口号。 

http://www.lryc.cn/news/608428.html

相关文章:

  • Leetcode 11 java
  • 论文笔记:Bundle Recommendation and Generation with Graph Neural Networks
  • (1-8-1) Java -XML
  • [ LeetCode-----盛最多的水]
  • 如何快速解决PDF解密新方法?
  • SpringBoot启动项目详解
  • 丝杆升降机在物流运输领域有哪些应用场景
  • 大模型Agent记忆的主流技术与优缺点解析
  • 23th Day| 39.组合总和,40.组合总和II,131.分割回文串
  • 数据结构---概念、数据与数据之间的关系(逻辑结构、物理结构)、基本功能、数据结构内容、单向链表(该奶奶、对象、应用)
  • 模型 古德哈特定律(Goodhart’s law)
  • 跨语言AI服务指标收集实战
  • 【深度学习】【三维重建】windows11环境配置PyTorch3d详细教程
  • 智能图书馆管理系统开发实战系列(五):前后端集成 - koffi调用与接口设计
  • WAIC引爆AI,智元机器人收购上纬新材,Geek+上市,157起融资撑起热度|2025年7月人工智能投融资观察 · 极新月报
  • FreeRTOS源码分析一:task启动(RISCV架构)
  • 【图像处理基石】用Python实现基础滤镜效果
  • PCB铜浆塞孔工艺流程
  • 网页操作自动化解决方案:如何用Browser-Use+CPolar提升企业运营效率
  • openwrt下安装istore(基于pve)
  • CCF IVC 2025“汽车安全攻防赛” -- Crypto -- WriteUp
  • ESP2025年6月认证C++八级( 第三部分编程题(2)遍历计数)
  • 线程池的实现
  • 【python】转移本地安装的python包
  • 【语音技术】意图与语料
  • 从下单到发货:如何清晰表达发货时间
  • Python编程基础与实践:Python条件语句入门:掌握if, else, 和elif
  • Android动画实现控件形状、大小逐渐过渡
  • Agentic RAG:自主检索增强生成的范式演进与技术突破
  • Waterfox水狐浏览器、火狐浏览器外观修改