本页导航
article
添加登录并启用全局前置守卫
AI摘要
本文介绍了为VuePress项目添加登录功能并启用全局前置守卫的步骤。主要内容包括:新增登录页面和路由,添加登录验证逻辑,安装并使用模态对话框插件,在enhanceApp.js中执行路由守卫逻辑。同时,为了弥补enhanceApp.js在页面刷新或直接访问路由时无法触发的不足,还创建了全局组件LoginInfo,确保未登录时能重定向到登录页,最后在主题配置中完成相应设置。
新增登录页面
在.vuepress/components新增Login.vue
<template>
<div class="login-container">
<div class="login-form">
<Date />
<div class="form-row">
<div class="form-header">账号</div>
<input type="text" class="form-control" v-model="username">
</div>
<div class="form-row">
<div class="form-header">密码</div>
<input type="password" class="form-control" v-model="password">
</div>
<div class="btn-row">
<button class="btn" @click="login">
登录
</button>
</div>
</div>
</div>
</template>
<script>
import { STORAGE_KEY } from '../login/helper'
import { DialogToast } from 'v-dialogs'
export default {
data () {
return {
username: '',
password: ''
}
},
methods: {
login() {
let { time, token } = this.$themeConfig.loginInfo
if (this.username && this.password ) {
const data = JSON.stringify({
name: this.username,
time: Math.round(new Date().getTime()/1000),
expire: 86400 * time,
accesskey: token
})
window.localStorage.setItem(STORAGE_KEY, data)
this.$router.push({ name: 'v-413f20b7' }, () => {
DialogToast('登录成功', {
messageType: 'success',
position: 'topCenter',
closeTime: 3
})
}, (error) => {
DialogToast('系统错误', {
messageType: 'error',
position: 'topCenter',
closeTime: 3
})
})
} else {
DialogToast('账号或密码错误!', {
messageType: 'error',
position: 'topCenter',
closeTime: 3
})
}
}
}
}
</script>
<style lang="stylus">
.login-container {
width: 100%;
height: 100vh;
background-color: #2d3a4b;
}
.form-row {
display: flex;
flex-direction: row;
margin-top: 1rem;
}
.login-form {
padding: 1rem;
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #2d3a4b;
width:50%;
position:absolute;
left:50%; /* 定位父级的50% */
top:50%;
transform: translate(-50%,-50%); /*自己的50% */
}
.login-form .btn-row {
margin: 2rem auto;
}
.login-form .btn {
padding: 0.6rem 2rem;
outline: none;
background-color: #60C084;
color: white;
border: 0;
width: 13rem;
}
.login-form .form-header {
color: #f08d49;
margin-bottom: 0.5rem;
width: 3rem;
padding-top: .5rem;
}
.login-form .form-control {
padding: 0.6rem;
border: 2px solid #ddd;
margin-bottom: 0.5rem;
box-sizing: border-box;
outline: none;
flex: 1;
transition: border 0.2s ease;
}
.login-form .form-control:focus {
border: 2px solid #aaa;
}
</style>
新增登录页面路由/login
module.exports = {
...
additionalPages: [
{
path: '/login/',
frontmatter: {
layout: 'Login', //.vuepress/components新增的页面,名称得同名
article: false // 设置为非文章页
}
}
],
themeConfig: {
...
}
}
添加登录验证逻辑helper.js
export const STORAGE_KEY = 'employee-auth'
export function checkAuth() {
// 通过 localStorage 对象从浏览器本地存储中获取指定键(STORAGE_KEY)对应的值
// 使用 JSON.parse 将其转换为对象。
const auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
// Object.keys(auth) 返回一个由对象的键组成的数组,而 .length 属性表示数组的长度,因此这个条件检查对象是否非空。
// 返回值是一个布尔值。如果 auth 存在且至少包含一个键,那么表达式的结果为 true,否则为 false。
return auth && Object.keys(auth).length
}
添加路由守卫
安装v-dialogs模态对话框插件
:::: el-tabs
::: el-tab-pane label=yarn
yarn add v-dialogs -D
::: ::: el-tab-pane label=npm
npm i v-dialogs -D
::: ::::
然后在./vuepress/enhanceAPP.js执行路由守卫逻辑
//引入登录验证逻辑helper.js
import { checkAuth, STORAGE_KEY } from './login/helper';
const whiteList = ['/login/', '/']
export default ({ Vue,router }) => {
Vue.mixin({
mounted() {
//全局注册v-dialogs
let dialog = require('v-dialogs')
Vue.use(dialog)
let { isLogin, token } = this.$themeConfig.loginInfo
// 是否开启登录
if (isLogin) {
router.beforeEach(async (to, from, next) => {
if (checkAuth()) {
if (to.path === '/login/') {
// if is logged in, redirect to the home page
next({ path: '/' })
} else {
//转成json对象
let auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
// auth存在并且accesskey是config.js里的token的值
if (auth && auth.accesskey === token) {
// 存值时间戳 + 有效时间 = 过期时间戳
// 如果当前时间戳大于过期时间戳说明过期了,删除值并返回提示
if ((Date.now() / 1000) > (auth.time + auth.expire)) {
localStorage.removeItem(STORAGE_KEY)
//重定向到登录页,name通过vue.js devtools获取
next({ name: 'v-18a8437b' })
} else {
next();
}
} else {
dialog.DialogAlert('登录已过期,请重新登录!', function () {
localStorage.removeItem(STORAGE_KEY)
//重定向到登录页,name通过vue.js devtools获取
next({ name: 'v-18a8437b' })
}, {
messageType: 'warning'
})
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
//重定向到登录页,name通过vue.js devtools获取
next({ name: 'v-18a8437b' })
}
}
});
} else {
localStorage.removeItem(STORAGE_KEY)
}
},
});
};
完善路由守卫
enhanceAPP.js在页面刷新和直接在浏览器访问某个路由时并不会触发,所以需要注册一个全局组件LoginInfo,在没有token执行页面刷新和浏览器直接访问时重定向到登录页,弥补enhanceAPP.js缺失的功能
在.vuepress/components中添加LoginInfo.vue,代码如下
<template></template>
<script>
import { checkAuth, STORAGE_KEY } from '../login/helper';
export default {
mounted() {
// 是否开启登录
let { isLogin } = this.$themeConfig.loginInfo
if (!checkAuth() && this.$route.path !== '/login/' && isLogin) {
this.$router.push('/login/')
}
},
};
</script>
config.js的themeConfig添加如下配置
module.exports = {
...
themeConfig: {
loginInfo: {
isLogin: false, // 是否开启登录
token: Math.random().toString(32).slice(2),
time: 1 // token过期时间,单位:天
},
}
...
}
最后更新于 2026-02-18 18:15