登录概述
登录业务流程
- 输入用户名和密码
- 调用后台接口验证
- 根据响应状态跳转到项目主页
登录业务的技术点
- http是无状态的
- 通过cookie在客户端记录状态
- 通过session在服务端记录状态
- 通过token方式维持状态
登录——token原理分析
服务器根据携带的token值去验证你是哪个用户,根据操作返回不同的结果。token主要进行客户端与服务器端之间身份校验的,token是保证登录成功之后的唯一身份令牌。
具体实现
完成后的效果
创建login组件
1、在components文件夹下创建 Login.vue 文件
Login.vue中的script采用以下写法:
<style lang="less" scoped>
</style>
lang=“less” :支持less写法,需要下载less-loader、less(在vue ui依赖中下载) scoped :样式只在当前组件中有效,避免了各个组件间的样式冲突问题
2、配置路由实现重定向
使用redirect进行路由重定向
const router = new Router({
routes: [
{ path: '/', redirect: '/login' },
{ path: '/login', component: Login }
]
})
3、在 App.vue 组件中放置路由占位符
<template>
<div id="app">
<!
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
登录布局设计
1、设置背景色
<template>
<div class="login_container">
<style lang='less' scoped>
.login_container {
background-color:
height: 100%;
}
背景全屏设置:让html、body、最外层盒子高度均为100%。
html,
body,
height: 100%;
margin: 0;
padding: 0;
}
在 main.js 中导入全局样式表
import './assets/css/global.css'
2、 绘制登录盒子
<template>
<div class="login_container">
<div class="login_box">
.login_box {
height: 300px;
width: 450px;
background-color:
border-radius: 3px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
3、盒子内部设计
图片 + 登录的表单
<template>
<div class="login_container">
<div class="login_box">
<!
<div class="image_box">
<img src="../assets/logo.png" alt="" />
</div>
<!
<el-form
class="login-form"
ref="loginFormRef"
:model="loginForm"
:rules="loginFormRules"
>
<!
<el-form-item prop="username">
<el-input
v-model="loginForm.username"
prefix-icon="el-icon-user"
size="medium"
></el-input>
</el-form-item>
<!
<el-form-item prop="password">
<el-input
v-model="loginForm.password"
prefix-icon="el-icon-lock"
size="medium"
type="password"
></el-input>
</el-form-item>
<!
<el-form-item class="btns">
<el-button type="primary" @click="login">登录</el-button>
<el-button type="info" @click="resetLoginForm">重置</el-button>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script>
export default {
data() {
return {
loginForm: {
username: "admin",
password: "123456",
},
loginFormRules: {
username: [
{ required: true, message: "请输入登录名称", trigger: "blur" },
{
min: 3,
max: 10,
message: "长度在 3 到 10 个字符",
trigger: "blur",
},
],
password: [
{ required: true, message: "请输入登录密码", trigger: "blur" },
{
min: 6,
max: 15,
message: "长度在 6 到 15 个字符",
trigger: "blur",
},
],
},
};
},
methods: {
resetLoginForm() {
this.$refs.loginFormRef.resetFields();
},
login() {
this.$refs.loginFormRef.validate((valid) => {
if (!valid) return;
this.$http.post("login", this.loginForm).then((res) => {
if (res.data.meta.status == 200) {
this.$message.success("登录成功");
console.log(res);
window.sessionStorage.setItem("token", res.data.data.token);
this.$router.push("/home");
} else {
return this.$message.error("登录失败");
}
});
});
},
},
};
</script>
.login_box {
height: 300px;
width: 450px;
background-color:
border-radius: 3px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
.image_box {
height: 130px;
width: 130px;
border: 1px solid
border-radius: 50%;
padding: 10px;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
background-color:
img {
width: 100%;
height: 100%;
border-radius: 50%;
background-color:
}
}
}
4、form 表单组件学习
form表单
典型写法:
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
</el-form>
<script>
export default {
data() {
return {
form: {
name: ''
}
}
},
实现效果: :model=“form” 指定的是form表单要绑定的数据,在 data return { } 中定义 v-model=“form.name” 进行表单数据和输入框之间的双向绑定,数据对象中对应的属性
ref=“form” 是整个表单数据的引用,可以用来获取表单数据 :rules=“rules” 是提供表单验证功能,需要在 data return { } 中定义表单验证规则的对象,prop 属性为对应的验证规则字段
表单数据重置方法 使用 resetFields ,可以通过ref拿到表单的数据,然后调用该方法
this.$refs.loginFormRef.resetFields();
步骤:
- 在表单中添加引用ref=“loginFormRef”
- 给重置按钮增加点击监听事件@click=“xxx”
- 在处理方法中调用this.$refs.loginFormRef.resetFields()
表单验证
为 el-form 绑定一个验证规则 :rules=“rules” 是提供表单验证功能,需要在 data return { } 中定义表单验证规则的对象, prop 属性为对应的验证规则中的字段
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="活动名称" prop="name">
<el-input v-model="ruleForm.name"></el-input>
</el-form-item>
<script>
export default {
data() {
return {
ruleForm: {
name: ''
},
rules: {
name: [
{ required: true, message: '请输入活动名称', trigger: 'blur' },
{ min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
]}
步骤:
- 在data中创建验证规则对象rules
- 给表单el-form绑定验证规则对象 使用:rules =“rules”
- 给el-form-item项添加 prop=“xxx” ,即表示我们希望使用xxx验证规则验证item里的表单数据项
表单提交前预校验 先拿到表单的引用对象,然后调用 validate 方法
this.$refs.loginFormRef.validate((valid) => {
if (!valid) return;
this.$http.post("login", this.loginForm).then((res) => {
});
});
步骤:
- 给表单添加引用
- 给登录按钮添加点击事件
- 在处理函数中调用validate方法,根据其bool值决定请求/不发起请求
5、发送登录请求
login() {
this.$refs.loginFormRef.validate(async valid => {
if (!valid) return;
const { data: res } = await this.$http.post("login", this.loginForm);
if (res.meta.status === 200) {
return this.$message.success("登陆成功");
} else {
return this.$message.success("登陆失败");
}
});
}
login() {
this.$refs.loginFormRef.validate((valid) => {
if (!valid) return;
this.$http.post("login", this.loginForm).then((res) => {
if (res.data.meta.status == 200) {
this.$message.success("登录成功");
console.log(res);
} else {
return this.$message.error("登录失败");
}
});
});
}
6、登录后的处理
- 将登陆成功之后的 token 保存至客户端的 sessionStorage 中
项目中除了登录之外的其他API接口,必须在登录之后才能访问 token只应在当前网站打开期间生效,所以放在session里而不是local - 通过路由跳转至后台主页 this.$router.push
if (res.data.meta.status == 200) {
this.$message.success("登录成功");
console.log(res);
window.sessionStorage.setItem("token", res.data.data.token);
this.$router.push("/home");
}
新建 Home.vue 组件 然后添加路由规则
{ path: '/home', component: Home}
7、路由导航守卫控制页面访问权限
比如 /HOME 页面是在登录的情况下才允许访问,未登录时不能访问,而跳转到登录页面 在router/index.js中添加导航守卫
const router = new Router({
})
router.beforeEach((to, from, next) => {
if (to.path === '/login') return next()
const tokenStr = window.sessionStorage.getItem('token')
if (!tokenStr) return next('/login')
next()
})
export default router
8、退出登录
核心原理:清空token,这样后续请求不携带token,必须重新登录生成新token后才能访问页面。
在Home.vue组件中新增退出按钮,实现退出功能
<el-button type="info" @click="logout">退出</el-button>
methods: {
logout() {
window.sessionStorage.clear();
this.$router.push("/login");
},
|