1、配置src/views/login.vue
<template> <div class="container"> <div class="content"> <h2>用户登录</h2> <el-form ref="loginFormRef" :model="loginForm" status-icon :rules="rules" label-width="120px" class="demo-loginForm" > <el-form-item label="用户名" prop="UId"> <el-input v-model="loginForm.UId" type="text" autocomplete="off" /> </el-form-item> <el-form-item label="密码" prop="Pwd"> <el-input v-model="loginForm.Pwd" type="password" autocomplete="off" /> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm(loginFormRef)" >提交</el-button > <el-button @click="resetForm(loginFormRef)">重置</el-button> </el-form-item> </el-form> </div> </div> </template> <script setup> // 导入ref,reactive响应类型 import { ref, reactive, toRefs } from "vue"; // 导入路由 import { useRouter } from "vue-router"; // 导入store对象 import { useStore } from "vuex"; const router = useRouter(); // 定义store对象 const store = useStore(); // 定义ref对象:绑定表单 const loginFormRef = ref(); // 定义reactive对象:组件数据 const data = reactive({ // 定义表单对象 loginForm: { UId: "", Pwd: "" }, // 定义表单验证规则 rules: { UId: [ { required: true, message: "请输入用户名", trigger: "blur" }, { min: 3, max: 18, message: "长度在3-18个字符", trigger: "blur" }, ], Pwd: [ { required: true, message: "请输入密码", trigger: "blur" }, { min: 3, max: 18, message: "长度在3-18个字符", trigger: "blur" }, ], }, }); const { loginForm, rules } = toRefs(data); // 提交表单 const submitForm = (formEl) => { if (!formEl) return; formEl.validate((valid) => { if (valid) { // store.dispatch("login", data.loginForm); router.push("/"); } else { console.log("error submit!"); return false; } }); }; // 重置表单 const resetForm = (formEl) => { if (!formEl) return; formEl.resetFields(); }; </script> <style lang="scss" scoped> .container { width: 100vw; height: 100vh; background: linear-gradient(to bottom, #134857, #a1cdda); // 背景采用向下渐变 display: flex; // 弹性布局 justify-content: center; // 水平布局 flex-start center flex-end align-items: center; //垂直布局 .content { width: 400px; border: 0px solid #ccc; border-radius: 6px; //圆角 padding: 20px; h2 { text-align: center; padding-bottom: 20px; color: white; } :deep(label) { color: #eee; } } } </style>
2、在scr\api文件夹下,建立login.js,使用axios获取登录后台登录token
此处使用测试数据,模拟token
// 引入get请求方法和post请求方法 import { $get, $post } from "../utils/request.js"; // 登录方法 export const $login = async (params) => { if (params.UId === "admin" && params.Pwd === "admin") { return { success: true, data: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImN0eSI6IkpXVCJ9.eyJVc2VySWQiOiJhZG1pbiIsIlVzZXJOYW1lIjoiYWRtaW4iLCJOaWNrTmFtZSI6Iui2hee6p-euoeeQhuWRmCIsImh0dHA6Ly9zY2hlbWFzLm1pY3Jvc29mdC5jb20vd3MvMjAwOC8wNi9pZGVudGl0eS9jbGFpbXMvcm9sZSI6ImFkbWluIiwiUm9sZSI6ImFkbWluIiwiZXhwIjoxNjY1OTA3NDM3LCJpc3MiOiJqd3RJc3N1ZXIiLCJhdWQiOiJqd3RBdWRpZW5jZSJ9.XXX", message: "登录成功", }; } else { return { success: false, data: "", message: "登录失败", }; } // 以上是模拟数据,用户名和密码均为admin,实际业务中在后台获取数据 // let { data } = await $get("Login/LoginIn", params); // return data; };
3、修改scr\store\index.js文件,在vuex中的actions: {}中新建登录(login)、退出(loginout)方法,
3.1、引入
import { createStore } from "vuex"; import router from "../router"; import jwttoken from "jwt-decode"; import { $setHeader } from "../utils/request.js"; import { $msg } from "../utils/msg.js"; import { $login } from "../api/login.js";
3.2、重写actions: {}
actions: { // 执行登陆操作 login({ commit }, userInfo) { return new Promise((resolve, reject) => { $login({ UId: userInfo.UId, Pwd: userInfo.Pwd, }) .then((res) => { if (res.success) { const token = res.data; commit("setToken", token); // 根据token解析用户,存储到sessionStorage sessionStorage.setItem("UserId", jwttoken(token).UserId); sessionStorage.setItem("UserName", jwttoken(token).UserName); // 将token信息添加到请求头中,后端根据token验证权限 $setHeader("Authorization", "Bearer " + token); router.push("/"); $msg(res.message); resolve(); } else { $msg(res.message, "error"); } }) .catch((err) => { reject(err); }); }); }, // 执行退出操作 loginout({ commit }) { commit("setToken", ""); // 清除浏览器缓存 sessionStorage.clear(); localStorage.clear(); // 跳转到登录页 router.replace("/login"); }, },
4、修改login.vue中的登录和layoutHeader.vue中的退出
src\views\login.vue部分
// router.push("/"); store.dispatch("login", data.loginForm); src\components\layoutHeader.vue部分 const loginout = () => { // router.push("/login"); store.dispatch("loginout"); };
5、添加路由守卫
5.1、src\router下新建permission.js
import router from "./index"; import store from "../store"; const whiteList = ["/login"]; router.beforeEach((to, from, next) => { if (store.state.token) { if (to.path === "/login") { next("/"); } else { next(); } } else { if (whiteList.includes(to.path)) { next(); } else { next("/login"); } } });
5.2、将permission.js添加到main.js
import "./router/permission"; //引入路由守卫