在 VuePress 中增加使用者登入
VuePress 是 Vuejs 官方提供的一個快速建設文件站點的工具,在簡單配置好功能後,需要做的事情就剩下寫好一個個 Markdown 文件。
因為 VuePress 提供了可以在 Markdown 中使用 Vue 的能力,所以有時候,希望可以在它的文件功能基礎上增加部分常規功能,比如使用者登入;有團隊希望公司建設的文件內容僅公司員工可檢視,因為有可能會有涉及內容保密的部分
VuePress 本身的安裝配置過程不再贅述,可參考官方文件,本文將介紹使用 v-dialogs 對 VuePress 增加使用者登入功能的進行改造,僅作為拋磚引玉,更多的需求,大家可以自由發揮想象。
安裝外掛
安裝 v-dialogs
外掛,將會使用它的模態視窗 (Modal) 和訊息通知 (Alert) 的功能
# npm
npm i v-dialogs -D
# yarn
yarn add -D v-dialogs
複製程式碼
建立登入表單
新增 Login.vue
檔案用於登入表單,它將使用模態視窗(Modal)進行展示
<template>
<div class="login-form">
<div class="form-header">User Name</div>
<div>
<input type="text" class="form-control" v-model="username">
</div>
<div class="form-header">Password</div>
<div>
<input type="password" class="form-control" v-model="password">
</div>
<div class="btn-row">
<button class="btn" @click="login">
OK
</button>
</div>
</div>
</template>
<script>
import { STORAGE_KEY } from './helper'
export default {
data () {
return {
username: '',
password: ''
}
},
methods: {
login () {
if (this.username && this.password) {
const data = JSON.stringify({
name: this.username,
time: new Date().getTime()
})
// 登入成功後的邏輯處理,這裡將資料儲存在 localStorage 中僅作為功能演示
window.localStorage.setItem(STORAGE_KEY, data)
// 關閉視窗
this.$emit('close', true)
} else {
this.$dlg.alert('Please complete the content', {
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>
複製程式碼
VuePress 配置
在 /.vuepress
位置新增 enhanceApp.js
檔案,該檔案是 VuePress 對 應用級別的配置 的配置檔案,檔案 export default
了一個鉤子函式,並接受一個包含了一些應用級別屬性的物件作為引數。你可以使用這個鉤子來安裝一些附加的 Vue 外掛、註冊全域性元件,或者增加額外的路由鉤子等
import { checkAuth } from './login/helper'
import Login from './login/Login'
export default ({
Vue,
options,
router,
siteData
}) => {
Vue.mixin({
mounted() {
const doCheck = () => {
if (!checkAuth()) {
this.$dlg.modal(Login, {
width: 300,
height: 350,
title: 'Employee login',
singletonKey: 'employee-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 對全域性進行了混入操作,所以在每個文件頁面被訪問後都會觸發該 mounted()
生命週期進行使用者許可權的校驗。在這裡需要特別說明的是,原來對於許可權檢查的操作,本是希望在 Vue Router
的路由守衛中處理,但由於 瀏覽器的 API 訪問限制 原因,Vue 外掛在註冊的過程中因為需要使用到瀏覽器的API (window 或 document),但在編譯為靜態檔案的過程中,需要通過 Node.js 服務端渲染,因此所有的 Vue 相關程式碼都應當遵循 編寫通用程式碼 的要求。簡而言之,請確保只在 beforeMount 或者 mounted 訪問瀏覽器 / DOM 的 API
v-dialogs
在註冊的過程中需要使用到 document 這個物件,所以在編譯的過程中會出現 document is not defined
的錯誤資訊,基於上述的原因,對於功能許可權的檢查在 mounted
生命週期中執行,並將該操作進行全域性混入,才能達到全域性校驗的效果
上述的程式碼編寫部署並重新構建後,就會在每個文件頁面中執行使用者身份校驗
- 未登入,則彈出模態視窗要求輸入身份資訊進行校驗
- 已登入時就顯示正確的文件內容
例項
可以訪問下面的站點進行線上預覽登入功能的改造
輸入任意使用者名稱和密碼進行體驗即可