先看效果
程序目录
这里用到了Vuex,用于更新页面显示的倒计时,当然页面不显示不用也可以。Vuex相关文章前面有介绍,在此就简单描述了
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
export default new Vuex.Store({
state:{
user:{
second:0, //倒计时用于界面更新用 如果不需要界面更新则不需要使用此数据
}
},
mutations:{
setSecond(state,second){
state.user.second=second;
}
},
getters:{
userSecond(state){
return state.user.second
}
}
})
除此之外主要内容就分为两块:一个是自己写的一个关于登陆登出的loginBll(因为以前是干后端的所以就这么命名了ヽ(ー_ー)ノ),另一块就是路由守卫与一个定时器。
路由守卫
路由守卫写在了main.js中了
main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
import loginBll from './loginBll'
Vue.config.productionTip = false
Vue.prototype.$store = store;
Vue.prototype.$loginBll = loginBll;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: {App},
template: '<App/>',
mounted() {
this.$loginBll.init(this.$store);
//一定时间没有操作退出
setInterval(() => {
if (this.$route.path != '/') {
if (localStorage.getItem('second') > 0) {
this.$loginBll.secondDiff();
} else {
this.$loginBll.logout();
this.$router.push('/');
}
}
}, 1000)
//后置路由钩子用于时间内浏览器打开 页面也能正常使用
this.$router.afterEach((to, from) => {
let name = localStorage.getItem('name');
if (to.path != '/' && name) {
this.$loginBll.restoreSecond();
}
})
}
})
//路由守卫
router.beforeEach((to, from, next) => {
let name = localStorage.getItem('name');
if (name == null) {
if (to.path == '/') {
next();
} else {
next('/');
}
} else {
next();
}
})
loginBll
为了在此处能控制Vuex中的数值变化,故通过init方法将store传入。
export default {
store:null,
allSecond:10,//倒计时总秒数
init(store){
this.store=store;
},
/***
* 倒计时减秒
* @returns 剩余秒数
*/
secondDiff() {
if (!this.store){
console.error('incorrect init')
return;
}
let second = localStorage.getItem('second');
if (second && second > 0) {
localStorage.setItem('second', --second)
}
this.store.commit('setSecond',second);
},
/***
* 登录
* @param name 用户名称
*/
login(name) {
if (!this.store){
console.error('incorrect init')
return;
}
localStorage.setItem('name', name);
this.store.commit('setSecond',this.allSecond);
localStorage.setItem('second', this.allSecond)
},
/***
*退出登录
*/
logout() {
localStorage.removeItem('name');
localStorage.removeItem('second')
},
/***
* 重新计时
*/
restoreSecond(){
if (!this.store){
console.error('incorrect init')
return;
}
this.store.commit('setSecond',this.allSecond);
localStorage.setItem('second',this.allSecond);
}
}
这里为什么用localStorage记录时间与用户名称而不用Vuex直接记录那,因为Vuex在每次刷新页面的时候都会回复原状,这与登陆要求不符,所以使用能够跨浏览器标签并且刷新不会丢失的localStorage来记录用户登陆与计时信息。
登录页
<template>
<div class="login-main">
<div>
<input placeholder="name" v-model="name">
</div>
<div>
<input type="password" placeholder="password" v-model="password">
</div>
<div>
<button @click="login">login</button>
</div>
</div>
</template>
<script>
export default {
name: "Login",
data() {
return {
name: 'admin',
password: 123
}
},
methods: {
login() {
if (this.name == 'admin' && this.password == 123)
{
this.$loginBll.login(this.name);
}
this.$router.push('/hello')
}
}
}
</script>
<style scoped>
.login-main {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -100%);
}
.login-main > div {
margin-top: 10px;
}
</style>
主页
<template>
<div class="hello-main">
倒计时 <strong>--{{$store.getters.userSecond}}秒--</strong>返回登录页
<div>
<button @click="doSomeThing">操作</button>
</div>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data() {
return {}
},
methods: {
doSomeThing() {
this.$loginBll.restoreSecond();
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.hello-main {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -100%);
text-align: center;
}
</style>
其实这段代码是有bug的,应该但对每个用户单独计数的,现在所有用户都共用一个second,但这里就是一个demo (✪ω✪)