vue2 一分钟不动系统 系统将进行锁定
1、创建:inactivityTimer.js
let timer = null
const timeout = 60000 // 60秒锁定export function startInactivityTimer(store, router) {// 检查是否应该锁定function shouldLock() {return router?.currentRoute?.path !== '/login'}// 重置计时器function resetTimer() {clearTimeout(timer)if (shouldLock()) {timer = setTimeout(() => {// console.log('触发锁定操作...')store.dispatch('Lock', null, { root: true }).then(() => {// console.log('锁定成功,跳转到/lock页面')router.push('/lock')})// .catch(err => console.error('锁定失败:', err))}, timeout)}}// console.log('无操作检测初始化...')// 监听用户活动const events = ['mousemove', 'keypress', 'click', 'scroll']events.forEach(event => {window.addEventListener(event, resetTimer)// console.log(`已监听事件: ${event}`)})// 初始化计时器resetTimer()
// console.log('无操作检测已启动,5秒后锁定')
}export function stopInactivityTimer() {clearTimeout(timer)window.removeEventListener('mousemove', resetTimer)window.removeEventListener('keydown', resetTimer)window.removeEventListener('click', resetTimer)window.removeEventListener('scroll', resetTimer)
}
2、进行拦截 (不拦截 从地址栏可以直接进入)
let isShow = getLocked() == 'false' ? false : getLocked() == 'true' ? true : nullif (getToken() && isShow) {if (!isPathMatch('/lock', to.path)) {next({ path: '/lock' })NProgress.done()return}}
3、开始运行程序 main
const vm = new Vue({el: '#app',router,store,render: h => h(App),mounted() {// 启动无操作检测,传递store和routerstartInactivityTimer(this.$store, this.$router)}
})
4、状态进行管理 vuex user.js
actions: {// 锁定系统Lock({ commit }) {return new Promise(resolve => {commit('SET_LOCKED', true)setLocked(true)resolve()})},// 解锁系统Unlock({ commit }) {return new Promise(resolve => {commit('SET_LOCKED', false)setLocked(false)resolve()})}
}mutations:{SET_LOCKED: (state, locked) => {state.locked = locked}
}
5、存储本地
export function getLocked() {return Cookies.get(lockedKey)
}export function setLocked(val) {return Cookies.set(lockedKey, JSON.stringify(val))
}export function removeLocked() {return Cookies.remove(lockedKey)
}
6、锁定页面
<template><div class="lock-page"><div class="lock-container"><div class="user-info"><img :src="userInfo.avatar || require('@/assets/images/profile.jpg')" class="avatar"><div class="name">{{ userInfo.name || '用户' }}</div></div><el-form ref="form" :model="form" class="lock-form"><el-form-item prop="password"><el-inputv-model="form.password"type="password"placeholder="请输入密码进行解锁"@keyup.enter.native="handleUnlock"><template #prefix><i class="el-icon-lock"></i></template></el-input></el-form-item><el-buttontype="primary"class="unlock-btn"@click="handleUnlock">解锁系统</el-button></el-form></div></div>
</template><script>
import { mapGetters } from 'vuex'export default {name: "LockScreen",data() {return {form: {password: ''}}},computed: {...mapGetters(['userInfo'])},methods: {handleUnlock() {this.$refs.form.validate(valid => {if (valid) {this.$store.dispatch('Unlock').then(() => {// 返回之前的路由或首页const redirect = this.$route.query.redirect || '/'this.$router.push(redirect)})}})}}
}
</script><style scoped lang="scss">
.lock-page {width: 100%;height: 100vh;background-image: url("../../assets/images/login-bg.png");background-size: cover;display: flex;justify-content: center;align-items: center;.lock-container {width: 360px;padding: 30px;background: rgba(255, 255, 255, 0.9);border-radius: 6px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);text-align: center;.user-info {margin-bottom: 20px;.avatar {width: 80px;height: 80px;border-radius: 50%;margin-bottom: 10px;border: 2px solid #fff;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);}.name {font-size: 16px;color: #333;}}.unlock-btn {width: 100%;margin-top: 10px;}}
}
</style>