背景介紹
VuePress是個不錯的能基於Markdown快速構建靜態網站的框架,初步來說,對外訪問都是透明的。
但是可能因為一些保密需要,有些站點的文檔,我們希望控制一下訪問,所以我們借着別人的輪子記錄下怎么給VuePress實現簡單版本的全局登錄驗證彈窗。
給項目添加彈窗插件
npm i v-dialogs -D
新建Login.vue
和Helper.js
Login.vue
這是構建一個登錄框,基於v-dialogs
插件的。
里面有一個簡單的表單判斷,代碼里面預埋了一些username和password,有符合的就放過了,你也可以換成你接口的邏輯。
# .vuepress\login\Login.vue
<template>
<div class="login-form">
<div class="form-header">賬號</div>
<div>
<input type="text" class="form-control" v-model="username">
</div>
<div class="form-header">密碼</div>
<div>
<input type="password" class="form-control" v-model="password">
</div>
<div class="btn-row">
<button class="btn" @click="login">
登錄
</button>
</div>
</div>
</template>
<script>
import { STORAGE_KEY } from './helper'
export default {
data () {
return {
username: '',
password: ''
}
},
methods: {
login ()
{
if (this.username && this.password)
{
var userAndWords = { 'user1': 'password1', 'user2' : 'password2'}
var isMatchUser = false
for(var key in userAndWords)
{
var tempUser = key;
var tempPassword = userAndWords[key]
if(this.username === tempUser && this.password === tempPassword)
{
isMatchUser = true
break;
}
}
if(isMatchUser)
{
const data = JSON.stringify({
name: this.username,
time: new Date().getTime()
})
window.localStorage.setItem(STORAGE_KEY, data)
this.$emit('close', true)
}
else{
this.$dlg.alert('抱歉,賬號密碼不對', {
messageType: 'warning'
})
}
}
else {
this.$dlg.alert('請輸入賬號密碼', {
messageType: 'warning'
})
}
}
}
}
</script>
<style lang="stylus">
.login-form
padding: 1rem
display flex
flex-direction column
box-sizing border-box
.btn-row
margin-top 1rem
.btn
padding 0.6rem 2rem
outline none
background-color #60C084
color white
border 0
.form-header
color #666
margin-bottom 0.5rem
.form-control
padding 0.6rem
border 2px solid #ddd
width 100%
margin-bottom 0.5rem
box-sizing border-box
outline none
transition border 0.2s ease
&:focus
border 2px solid #aaa
</style>
賬號和密碼驗證通過之后,我們往STORAGE_KEY
寫入了一個數據,以便后續刷新頁面檢查之前登錄結果,詳細判斷見下文。
helper.js
這是一個用來判斷是否登錄驗證通過的函數,如果返回true就算是驗證通過,返回false那就沒驗證通過了。
# .vuepress\login\helper.js
export const STORAGE_KEY = 'user_auth_xxxxxxxxxxxx'
// Do user authorization verify
export function checkAuth ()
{
var auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
return auth && Object.keys(auth).length
}
這個是判斷是否登錄過的函數,說直白點,就是上面的登錄成功后,會往這個key里面寫一個對象值,每次調用頁面之前,先走這個函數做一個檢查,如果拿出來的auth
是你覺得合法的,你就true
通過,不然就一直繼續彈登錄框了。
其實這里,我們也可以根據自己的需要,給拿到的auth
對象進一步做判斷,當然要怎么搞就看你自己了。比如我會加一個過期時間,一個小時過期:
export function checkAuth ()
{
var auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
console.log(auth)
if(auth && auth.time){
var preTime = new Date(auth.time)
var nowTime = new Date().setHours(-1)
if(nowTime > preTime)
{
return false;
}
return auth && Object.keys(auth).length
}
else
{
return false;
}
}
嵌入新增的文件到VuePress
找到.vuepress
下面的enhanceApp.js
,如果沒有可以新建一個。
import { checkAuth } from './login/helper'
import Login from './login/Login'
export default ({
Vue,
options,
router,
siteData
}) => {
Vue.mixin({
// 請確保只在 beforeMount 或者 mounted 訪問瀏覽器 / DOM 的 API
mounted() {
const doCheck = () => {
if (!checkAuth()) {
this.$dlg.modal(Login, {
width: 400,
height: 350,
title: '請登錄您的賬號',
singletonKey: 'user-login',
maxButton: false,
closeButton: false,
callback: data => {
if (data === true) {
// do some stuff after login
}
}
})
}
}
if (this.$dlg) {
doCheck()
} else {
import('v-dialogs').then(resp => {
Vue.use(resp.default)
this.$nextTick(() => {
doCheck()
})
})
}
}
})
}
其中Vue.mixin
是對全局混入插入,因為v-dialogs
插件在注冊的過程中需要使用到document
這個對象,所以這里一定要在beforeMount或者mounted時間來做。