安装插件

安装v-dialogs模态对话框插件

:::: el-tabs

::: el-tab-pane label=yarn

      yarn add v-dialogs -D
    

::: ::: el-tab-pane label=npm

      npm i v-dialogs -D
    

::: ::::

创建登录表单文件

添加helper.js

      export const STORAGE_KEY = 'employee-auth'

// Do user authorization verify
export function checkAuth () {
  const auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
  return auth && Object.keys(auth).length
}
    

添加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'

export default {
  name: 'Login',
  data () {
	return {
	  username: '',
	  password: ''
	}
  },
  methods: {
	login() {
		  let { expiration, 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 * expiration,
				accesskey: token
			})
			// 将用户数据存储到本地存储
			window.localStorage.setItem(STORAGE_KEY, data)
			// 跳转到首页
			this.$router.push('/', () => {
				// 显示登录成功提示
				dialog.DialogToast('登录成功', {
					messageType: 'success',
					position: 'topCenter',
					closeTime: 3
				})
			}, (error) => {
				// 显示系统错误提示
				dialog.DialogToast('系统错误', {
					messageType: 'error',
					position: 'topCenter',
					closeTime: 3
				})
			})
		} else {
			// 显示账号或密码错误提示
			dialog.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>
    

VuePress 配置

添加enhanceApp.js文件于/.vuepress

      import { checkAuth, STORAGE_KEY } from './login/helper';
import Login from './login/Login';

export default ({ Vue }) => {

  Vue.mixin({
    mounted() {
      //引入v-dialogs
      let dialog = require('v-dialogs')
      Vue.use(dialog)
      
      const doCheck = () => {
        if (!checkAuth()) {
          this.$dlg.modal(Login, {
            width: 700,
            height: 350,
            title: '请登录您的账号',
            singletonKey: 'employee-login',
            maxButton: false,
            closeButton: false,
          });
        } else {
            let val = localStorage.getItem(STORAGE_KEY)
            // 如果没有值就直接返回null
            if (!val)  return val
            // 存的时候转换成了字符串,现在转回来
            val = JSON.parse(val)
            // 存值时间戳 +  有效时间 = 过期时间戳
            // 如果当前时间戳大于过期时间戳说明过期了,删除值并返回提示
            if ((Date.now()/ 1000) > (val.time + val.expire)) {
              localStorage.removeItem(STORAGE_KEY)
              window.location.reload()
            }
        }
      };
      if (this.$dlg) {
        doCheck()
      } else {
        import('v-dialogs').then(resp => {
          Vue.use(resp.default)
          this.$nextTick(() => {
            doCheck()
          })
        })
      }
    },
  });
};
    

这样会在每个文档中进行用户授权验证

  • 如果未授权,则显示登录模态对话框
  • 如果获得授权,将访问 vuepress 文档

声明

作者: liyao

版权:本博客所有文章除特别声明外,均采用CCBY-NC-SA4.O许可协议。转载请注明!

最后更新于 2026-02-17 19:41 history