VuePress 中增加使用者登入功能

TerryZ發表於2019-11-28

在 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 生命週期中執行,並將該操作進行全域性混入,才能達到全域性校驗的效果

上述的程式碼編寫部署並重新構建後,就會在每個文件頁面中執行使用者身份校驗

  • 未登入,則彈出模態視窗要求輸入身份資訊進行校驗
  • 已登入時就顯示正確的文件內容

例項

可以訪問下面的站點進行線上預覽登入功能的改造

輸入任意使用者名稱和密碼進行體驗即可

原始碼

請訪問: github.com/TerryZ/vuep…

相關文章