一.项目介绍:
通过使用element ui组件库对页面进行布局,然后再通过路由守卫验证登录状态
验证登录:有些路由是需要登录的,判断状态
??1.没有登录:跳转到登录页
??2.登录:直接进入
??3.有些路由不需要登录,那就直接进入;
??ps:是否需要登录?--meta
二.效果展示:
?三.代码展示:
login.vue:登录页面
<template>
<div class="login-section">
<!-- :rules="rules" -->
<el-form
label-position="top"
label-width="100px"
class="demo-ruleForm"
:rules="rules"
:model="rulesForm"
status-icon
ref="ruleForm"
>
<el-form-item label="用户名" prop="name">
<el-input type="text" v-model="rulesForm.name"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="rulesForm.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('ruleForm')"
>提交</el-button
>
<el-button>重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { login } from "@/service/api";
export default {
data() {
return {
//存储数据的对象
rulesForm: {
name: "",
password: "",
},
rules: {
name: [
{ required: true, message: "请输入姓名", trigger: "blur" },
{ min: 2, max: 5, message: "长度3-5个", trigger: "blur" },
],
password: [
{ required: true, message: "请输入密码", trigger: "blur" },
{ min: 6, max: 12, message: "长度3-5个", trigger: "blur" },
],
},
};
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
//如果效验通过,在这里向后端发送用户名和密码
login({
name: this.rulesForm.name,
password: this.rulesForm.password,
}).then((data) => {
console.log(data);
if (data.code === 0) { //判断code为0,则登陆成功
localStorage.setItem("token", data.data.token);
window.location.href = "/";
}
if (data.code === 1) {//判断code为1.则登录失败,服务器会提示错误信息
this.$message.error(data.mes);
}
});
} else {
console.log("error submit!!");
return false;
}
});
},
},
};
</script>
<style lang="stylus">
.login-section
padding 0px 20px
</style>
?router:配置路由
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
import {userInfo}from '@/service/api.js'
import Home from '@/views/home/Home.vue'
import Store from '@/store'
const Edit=()=>import('@/views/user-space/edit');
const Space=()=>import('@/views/user-space/space');
const Login=()=>import('@/views/user-login/index');
const router = new Router({
mode:"history",
routes:[
{
path:'/',
name:"Home",
title:"首页",
component:Home
},
{
path:'/login',
name:"login",
title:"登录页",
component:Login,
meta:{
login: true
},
},
{
path:'/space',
name:"space",
title:"个人空间",
component:Space,
meta:{
login: true
},
},
,
{
path:'/edit',
name:"edit",
title:"编辑个人资料",
component:Edit,
meta:{
login: true
},
},
{
path:"*",
name:"noFound",
title:"未找到",
redirect:{
name:"Home"
}
},
]
});
//路由守卫
router.beforeEach(async (to,from,next)=>{
验证登录:
const token=localStorage.getItem('token');//获取login里的数据
const isLogin=!!token;//两个感叹号转布尔值
//进入路由的时候,向后端发送token,验证是否合法
const data =await userInfo();
Store.commit('chageUserInfo',data.data);
//判断是否需要登录:如果meta中的为true那么需要登录
if (to.matched.some(item=>item.meta.login)) {//需要登录
console.log("需要登录")
if (isLogin) {//已经登录但已经登陆就直接通过
if (data.error === 400) {
next({name:'login'});
localStorage.removeItem('token');//移除本地存储
return;
}
if (to.name=== 'login') {
next({name:'home'})
}else{
next();
}
next();
return;
}
if(!isLogin && to.name==='login') {//没有登陆,仍需要去登录页
next();
}
if(!isLogin && to.name !=='login') {//没有登陆,去的也不是登录页
next({name:"login"});
}
} else{
next();
}
})
export default router;
?vuex库:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state:{
userInfo: {}
},
getters:{
isLogin(state){
return !!Object.keys(state.userInfo).length;
}
},
mutations:{
chageUserInfo(state, data){
state.userInfo = data;
}
},
actions:{}
})
export default store;
header.vue:
<template>
<el-header style="height: auto;">
<div class="header">
<div class="header_c">
<el-row type="flex" justify="start" align="middle">
<el-col :span="6">
<a href="" class="logo"> </a>
</el-col>
<el-col :span="10" :offset="2"></el-col>
<el-col :span="6" :offset="3" class="avatar-box" v-show="isLogin">
<router-link :to="{ name: 'space' }">
<el-avatar
style="vertical-align: middle;"
shape="square"
size="medium"
:src="userInfo.avatar"
></el-avatar>
</router-link>
<router-link :to="{ name: 'space' }" class="user-name">{{
userInfo.name
}}</router-link>
<router-link :to="{ name: 'space' }" class="collection"
>发布菜谱</router-link
>
<a href="javascript:;" class="collection" @click="exit">退出</a>
</el-col>
<el-col :span="6" :offset="3" class="avatar-box" v-show="!isLogin">
<router-link :to="{ name: 'login' }" class="user-name"
>登录</router-link
>
<router-link :to="{ name: 'login' }" class="collection"
>注册</router-link
>
</el-col>
</el-row>
</div>
</div>
<div class="nav-box">
<div class="nav_c">
<Menus></Menus>
</div>
</div>
</el-header>
</template>
<script>
import Menus from "@/components/menus";
import { login_out } from "@/service/api";
export default {
name: "headers",
components: { Menus },
computed: {
isLogin() {
return this.$store.getters.isLogin;
},
userInfo() {
return this.$store.state.userInfo;
},
},
methods: {
exit() {
this.$confirm("真的退出吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(async () => {
const data = await login_out();
localStorage.removeItem("token");
window.location.href = "/";
});
},
},
};
</script>
<style lang="stylus">
.header
height 129px
background-color #c90000
.logo
display: block;
height: 129px;
width: 184px;
background url(https://s1.c.meishij.net/n/images/logo2.png) -15px 9px no-repeat;
.header_c, .nav_c
width 990px
margin 0 auto
.nav-box
height 60px
background-color #fff;
box-shadow 10px 0px 10px rgba(0,0,0,0.3)
.user-name
margin-left 5px
color #fff
.collection
margin-left 5px
color #fff
</style>
看到这里就没了,这篇文章主要写了美食杰项目的登录页面,傻瓜式教程,希望对大家有帮助!!!
|