前言
这篇文章主要分享一下基于Vue3 + TypeScript的项目,利用Mock.js模拟后端数据,axios实现请求来完成一个登录功能。
一、Vue3 + Element Plus + Mock.js + axios实现登录功能
1.登录页面配置路由、编写表单内容
在router/index.ts中配置路由:
编写登录表单,el-form中绑定的数据要和下面定义的内容保持一致。
效果如下:
2.编写表单校验规则
看下效果:
3.登录触发表单预验证
这里利用Element Plus的form中的validate方法对整个表单进校验。 这个表单节点叫做ruleFormRef,由于setup中是没有this的,我们不能像Vue2中,通过this.$refs.xxx来获取节点。我们去setup中利用ref再重新定义一个相同名称的变量就可以,然后,它们就会自动关联起来。
点击登录就触发校验:
点击登录按钮验证一下:
4.Mock.js模拟登录请求
关于Mock.js的使用,可以看一下之前记录的博客Mock.js学习。在Mock.js中模拟一个post请求,第一个参数是拦截的请求路径,第二个参数是拦截的请求方式,第三个参数是拦截之后的处理逻辑,回调函数中params就是请求体携带的参数。 然后在mock登录请求中限制一下用户名和密码,两者输入正确才能获取到token。token值利用Mock随机函数中来生成。
import Mock from 'mockjs'
// 登录接口
Mock.mock('/admin/login', 'post', (params) =>{
// 请求参数
// console.log('post请求传入的参数是:',params.body); //请求体内容 params.body就是post参数
let loginData = JSON.parse(params.body);
let data;
// 用户名和密码正确才会返回token
if(loginData.username=='admin' && loginData.password=='123456'){
data = Mock.mock({
"token": "@id", // 随机生成一个18位身份证,模拟生成token值
})
}
return {
status:200,
message:"请求登录成功!",
tData:data
}
});
5.Vue3引入使用axios
安装axios,输入如下命令即可:
npm install axios --save
在Vue3中按照了之前Vue2的写法进行引入挂载全局,会出现报错。
Vue3的写法如下:
直接在登录页面上引入axios,导入axios就可以直接使用啦~
然后调用一下Mock.js模拟的post登录请求:
验证一下:
输入正确的账号和密码,就可以获取到请求返回的数据,并且拿到token。
输入错误的账号密码,就不会返回token值了。
注意:mock只是模拟数据,不会在network中显示,只有真实的请求才会在network中显示。
登录成功,跳转到首页即可。
router.push("/home");
登录页完整代码如下:
<template>
<div class="loginContainer">
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="rules"
class="formStyle"
>
<el-form-item label="账号" prop="username">
<el-input v-model="ruleForm.username" type="text" autocomplete="off" />
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="ruleForm.password"
type="password"
autocomplete="off"
/>
</el-form-item>
<el-form-item class="loginStyle">
<el-button type="primary" @click="Login()">登录</el-button>
</el-form-item>
</el-form>
</div>
</template>
<!-- script标签中添加setup,那么就不用写setup函数和return了 -->
<script lang="ts" setup>
import { ref, reactive, toRefs } from "vue";
import axios from "axios";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import Cookies from "js-cookie";
// 表单数据
let ruleForm = reactive({
username: "",
password: "",
});
// 获取el-form组件对象 名称和上面表单绑定ref的一样,它们俩就会自动关联起来。
let ruleFormRef = ref();
// 校验密码的函数 传3个参数,并对参数利用ts进行类型约束
// 进行类型约束 rule的类型不确定,就用unknown; 密码是放在输入框的,就是string类型;
// 函数,里面有一个string类型的参数,是可选的
const validatePassword = (
rule: unknown,
value: string | undefined,
callback: (msg?: string) => void
) => {
// 判断value是否为空,如果value不存在,那么
if (!value) {
callback("密码不能为空!");
} else {
// 如果不为空,就直接调用函数不提示内容。
// 由于上面定义函数的参数是可选的,所以调用函数的时候可以不添加参数了
callback();
}
};
// 校验规则
const rules = reactive({
username: [
{ required: true, message: "用户名不能为空!", trigger: "blur" },
],
password: [{ required: true, validator: validatePassword, trigger: "blur" }],
});
// 获取路由对象
let router = useRouter();
// 获取vuex对象 useStore()方法创建store对象 Vue3的store相当于Vue2的this.$store
let store = useStore();
// 登录按钮操作
const Login = () => {
// 登录触发校验规则
// 由于ruleFormRef是通过ref定义的,操作它需要利用.value
// validate是element plus 中form表单的方法,获取到form表单以后就可以直接调用了。
ruleFormRef.value
.validate()
.then(() => {
// mock模拟请求
// 第一个参数是请求路径,第二个参数是携带的请求参数(username password)
axios
.post("/admin/login", {
// 用户名和密码绑定表单的内容
username: ruleForm.username,
password: ruleForm.password,
})
.then((res) => {
// console.log(res.data);
let token = res.data.tData.token; // 存储token
// console.log("登录成功获取token值:", token);
// 登录成功跳转到首页
router.push("/home");
});
})
.catch(() => {
// console.log("表单校验不通过");
});
};
</script>
<style lang="scss" scoped>
.loginContainer {
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.formStyle {
border: 1px solid rgb(236, 225, 225);
border-radius: 12px;
padding: 40px;
box-shadow: 0px 0px 36px rgba(0, 0, 0, 0.1);
.loginStyle {
display: flex;
justify-content: center;
}
}
}
</style>
二、面试题
1.前端登录流程
① 在登录页点击”登录“,前端会带着用户名和密码去调用后端的登录接口请求登录; ② 后端收到请求后,会验证用户名和密码,如果验证失败,会返回相关的错误信息,前端提示相应错误信息;如果验证成功,就会生成当前用户所对应的一个token值,并返回前端token; ③ 前端拿到token之后,将token存储起来(可以存储在localStorage、sessionStorage、cookie、vuex中),并跳转页面即登录成功; ④ 前端每一次向后端请求资源的时候都要携带后端签发的token。如果前端在发起下一次请求时携带了token,那么服务器就会根据提交的token值去验证你是哪个用户,从而根据你的操作去返回不同的结果; ⑤ 最后,在向后端发送其他请求时,我们一般需要在请求头中带上这个token值,在项目中我们通常把它封装在一个请求拦截器中,后端判断请求头中有无该token,有则验证该token,验证成功就会正常地返回数据,验证失败,比如过期,就会返回相应的错误码,前端拿到相关错误信息清除token,并且再回退到登录页。
2.token是什么?
token的意思是令牌,是用户第一次登录时,服务器生成的一段加密字符串,然后返回给客户端。 客户端每次向服务器请求资源的时候,只需要带上token去请求数据就行,不用再带着用户名和密码去请求,服务器直接解密token,就可以知道用户的相关信息。由于基本所有请求都需要携带toke,我们可以在请求拦截器中统一封装,让每个请求都能带上token。