Vue 担心系统数据泄露?手把手教你实现系统锁屏功能
本篇博客记录了后台管理系统实现锁屏功能的实现代码。不在电脑面前,担心系统数据被别人看到?不妨试一下做个锁屏功能,把系统锁住?
·
目录
一、前言
当我们离开电脑不工作时,相信很多人都会有锁屏的习惯。目的当然是不想随随便便让别人使用我们的电脑啦,我们后台管理系统也是同样的道理,有的时候可能暂时离开电脑,我们就可以把系统锁屏,只有知道登录密码才能登录继续使用系统。博主的后台UI框架使用的是iview-admin。
实现思路:准备一个锁屏页面,使用cookie标识当前系统是否是锁屏状态,当点击锁屏后跳转到锁屏页面,并保留当前的路由页面到缓存中。同时把标识改为锁屏中,当输入正确的登录密码后,把锁屏标识解锁,然后回到锁屏之前的页面。
二、效果图
三、实现代码
1、封装组件
写好锁屏页面,并封装成组件。博主的组件目录结构:
lockscreen.vue 代码:
<template>
<div @click="lockScreen" class="lock-screen-btn-con">
<Tooltip content="锁屏" placement="bottom">
<Icon type="md-lock" :size="24"></Icon>
</Tooltip>
</div>
</template>
<script>
import Cookies from "js-cookie";
const setLockBackSize = () => {
let x = document.body.clientWidth;
let y = document.body.clientHeight;
let r = Math.sqrt(x * x + y * y);
return parseInt(r);
};
export default {
name: "lockScreen",
props: {
value: {
type: Boolean,
default: false
}
},
methods: {
lockScreen() {
let lockScreenBack = document.getElementById("lock_screen_back");
lockScreenBack.style.transition = "all 3s";
lockScreenBack.style.zIndex = 10000;
lockScreenBack.style.boxShadow =
"0 0 0 " + this.lockScreenSize + "px #667aa6 inset";
this.showUnlock = true;
Cookies.set("last_page_name", this.$route.name); // 本地存储锁屏之前打开的页面以便解锁后打开
setTimeout(() => {
lockScreenBack.style.transition = "all 0s";
this.$router.push({
name: "locking"
});
}, 800);
Cookies.set("locking", "1");
}
},
mounted() {
let lockScreenBack;
if (!document.getElementById("lock_screen_back")) {
let lockdiv = document.createElement("div");
lockdiv.setAttribute("id", "lock_screen_back");
lockdiv.setAttribute("class", "lock-screen-back");
document.body.appendChild(lockdiv);
lockScreenBack = document.getElementById("lock_screen_back");
window.addEventListener("resize", () => {
let size = setLockBackSize();
this.lockScreenSize = size;
lockScreenBack.style.transition = "all 0s";
lockScreenBack.style.width = lockScreenBack.style.height = size + "px";
});
} else {
lockScreenBack = document.getElementById("lock_screen_back");
}
let size = setLockBackSize();
this.lockScreenSize = size;
lockScreenBack.style.transition = "all 3s";
lockScreenBack.style.width = lockScreenBack.style.height = size + "px";
}
};
</script>
unlock.less 代码:
.unlock-body-con{
position: absolute;
width: 400px;
height: 100px;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -200px;
transform-origin: center center;
z-index: 10;
.unlock-avator-con{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
box-sizing: border-box;
width: 100px;
height: 100px;
border-radius: 50%;
overflow: hidden;
border: 2px solid white;
cursor: pointer;
transition: all .5s;
z-index: 12;
box-shadow: 0 0 10px 2px rgba(255, 255, 255, .3);
.unlock-avator-img{
width: 100%;
height: 100%;
display: block;
z-index: 7;
}
.unlock-avator-cover{
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .6);
z-index: 11600;
position: absolute;
left: 0;
top: 0;
opacity: 0;
transition: opacity .2s;
color: white;
span{
display: block;
margin: 20px auto 5px;
text-align: center;
}
p{
text-align: center;
font-size: 16px;
font-weight: 500;
}
}
&:hover .unlock-avator-cover{
opacity: 1;
transition: opacity .2s;
}
}
.unlock-avator-under-back{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-45px,-50%);
box-sizing: border-box;
width: 100px;
height: 100px;
border-radius: 50%;
background: #667aa6;
transition: all .5s;
z-index: 5;
}
.unlock-input-con{
position: absolute;
height: 70px;
width: 350px;
top: 15px;
right: 0px;
.unlock-input-overflow-con{
position: absolute;
width: 100%;
height: 100%;
left: 0;
top: 0;
overflow: hidden;
.unlock-overflow-body{
position: absolute;
top: 0;
right: 0;
width: 100%;
height: 100%;
transition: all .5s ease .5s;
.unlock-input{
float: left;
display: block;
box-sizing: content-box;
height: 22px;
width: 230px;
font-size: 18px;
outline: none;
padding: 11px 10px 11px 30px;
border: 2px solid #e2ddde;
margin-top: 10px;
}
.unlock-btn{
float: left;
display: block;
font-size: 20px;
padding: 7px 26px;
cursor: pointer;
border-radius: 0 25px 25px 0;
border: 2px solid #e2ddde;
border-left: none;
background: #2d8cf0;
outline: none;
transition: all .2s;
margin-top: 10px;
&:hover{
background: #5cadff;
box-shadow: 0 0 10px 3px rgba(255, 255, 255, .2);
}
}
.click-unlock-btn{
background: #2b85e4 !important;
}
}
}
}
.unlock-locking-tip-con{
width: 100px;
height: 30px;
text-align: center;
position: absolute;
left: 50%;
margin-left: -50px;
bottom: -80px;
color: white;
font-size: 18px;
}
}
@keyframes unlock-in{
0% {
transform: scale(0);
}
80%{
transform: scale(0);
}
88% {
transform: scale(1.3);
}
100% {
transform: scale(1);
}
}
@keyframes unlock-out{
0% {
transform: scale(1);
}
60%{
transform: scale(1.2);
}
100% {
transform: scale(0);
}
}
.show-unlock-enter-active{
animation: unlock-in 1.4s ease;
}
.show-unlock-leave-to{
opacity: 0;
}
.show-unlock-leave-active{
transition: opacity .2s;
}
.unlock-con{
width: 100%;
height: 100%;
}
locking-page.vue 代码:
<template>
<div style="width: 100%;height: 100%;background: #667aa6">
<div class="unlock-con">
<unlock :show-unlock="showUnlock" @on-unlock="handleUnlock"></unlock>
</div>
</div>
</template>
<script>
import unlock from './unlock.vue';
import Cookies from 'js-cookie';
export default {
components: {
unlock
},
data () {
return {
showUnlock: false
};
},
methods: {
handleUnlock () {
let lockScreenBack = document.getElementById('lock_screen_back');
this.showUnlock = false;
lockScreenBack.style.zIndex = -1;
lockScreenBack.style.boxShadow = '0 0 0 0 #667aa6 inset';
this.$router.push({
name: Cookies.get('last_page_name') // 解锁之后跳转到锁屏之前的页面
});
}
},
mounted () {
this.showUnlock = true;
if (!document.getElementById('lock_screen_back')) {
let lockdiv = document.createElement('div');
lockdiv.setAttribute('id', 'lock_screen_back');
lockdiv.setAttribute('class', 'lock-screen-back');
document.body.appendChild(lockdiv);
}
let lockScreenBack = document.getElementById('lock_screen_back');
lockScreenBack.style.zIndex = -1;
}
};
</script>
unlock.vue 代码:
<style lang="less">
@import "../styles/unlock.less";
</style>
<template>
<transition name="show-unlock">
<div class="unlock-body-con" v-if="showUnlock" @keydown.enter="handleUnlock">
<div @click="handleClickAvator" class="unlock-avator-con" :style="{marginLeft: avatorLeft}">
<img class="unlock-avator-img" :src="avatarPath">
<div class="unlock-avator-cover">
<span><Icon type="md-unlock" :size="30"></Icon></span>
<p>解锁</p>
</div>
</div>
<div class="unlock-avator-under-back" :style="{marginLeft: avatorLeft}"></div>
<div class="unlock-input-con">
<div class="unlock-input-overflow-con">
<div class="unlock-overflow-body" :style="{right: inputLeft}">
<input ref="inputEle" v-model="password" class="unlock-input" type="password" placeholder="密码同登录密码" />
<button ref="unlockBtn" @mousedown="unlockMousedown" @mouseup="unlockMouseup" @click="handleUnlock" class="unlock-btn"><Icon color="white" type="ios-key"></Icon></button>
</div>
</div>
</div>
<div class="unlock-locking-tip-con">已锁定</div>
</div>
</transition>
</template>
<script>
import axios from '@/libs/api.request'
import Cookies from "js-cookie"
const localStorage = window.localStorage
export default {
name: "Unlock",
data() {
return {
avatorLeft: "0px",
inputLeft: "400px",
password: "",
check: null
};
},
props: {
showUnlock: {
type: Boolean,
default: false
}
},
computed: {
avatarPath() {
let headUrl = localStorage.getItem('userHeadUrl')
return headUrl;
}
},
methods: {
unlock() {
this.avatorLeft = "0px";
this.inputLeft = "400px";
this.password = "";
Cookies.set("locking", "0");
this.$emit("on-unlock");
},
handleClickAvator() {
this.avatorLeft = "-180px";
this.inputLeft = "0px";
this.$refs.inputEle.focus();
},
handleUnlock() {
if (this.password == "") {
this.$Message.error("请输入密码");
return;
}
// 将用户输入的密码this.password与数据库用户密码对比
let flag = false;
axios.request({
url: '/user/admin/vlied-password',
method: 'POST',
data: { password: this.password }
}).then(
res => {
if (res.data.code == '1001') {
this.unlock();
} else {
this.$Message.error(res.data.message)
}
}
);
},
unlockMousedown() {
this.$refs.unlockBtn.className = "unlock-btn click-unlock-btn";
},
unlockMouseup() {
this.$refs.unlockBtn.className = "unlock-btn";
}
}
};
</script>
unlock.vue 文件注意事项:
1、博主的用户头像路径是存储在 localStorage 里面,所以此处用到了 localStorage 取用户头像。
2、请求后台验证用户密码这个请求,大家可以根据自己的实际情况换成自己封装好的请求。
2、使用组件
找到 main.vue 文件,引入组件。
// 引入组件,根据自己组件所在位置修改
import lockScreen from "./components/lockscreen/lockscreen.vue"
// 注册组件
components: {
lockScreen
},
// 使用组件
<lock-screen style="margin-right: 10px;"></lock-screen>
3、修改路由
需要修改路由的判断,找到 router 目录下面的 index.js 文件
找到 beforeEach 方法,增加以下判断。
router.beforeEach((to, from, next) => {
iView.LoadingBar.start()
if (Cookies.get('locking') == '1' && to.name !== 'locking') {
// 判断当前是否是锁定状态
next({
replace: true,
name: 'locking'
});
} else if (Cookies.get('locking') == '0' && to.name == 'locking') {
next(false);
} else {
// 白名单
const token = getLocalStorageToken()
if (!token && to.name !== LOGIN_PAGE_NAME) {
// 未登录且要跳转的页面不是登录页
next({
name: LOGIN_PAGE_NAME // 跳转到登录页
})
} else if (!token && to.name === LOGIN_PAGE_NAME) {
// 未登陆且要跳转的页面是登录页
next() // 跳转
} else if (token && to.name === LOGIN_PAGE_NAME) {
// 已登录且要跳转的页面是登录页
next({
name: homeName // 跳转到homeName页
})
} else {
if (store.state.user.hasGetInfo) {
turnTo(to, store.state.user.access, next)
} else {
store.dispatch('getUserInfo').then(user => {
// 拉取用户信息,通过用户权限和跳转的页面的name来判断是否有权限访问;access必须是一个数组,如:['super_admin'] ['super_admin', 'admin']
turnTo(to, user.access, next)
}).catch(() => {
setToken('')
next({
name: 'login'
})
})
}
}
}
})
在 routers.js 增加locking-page.vue的路由
{
path: '/locking',
name: 'locking',
meta: {
hideInMenu: true
},
component: () => import('_c/main/components/lockscreen/components/locking-page.vue')
}
到此,就完成了,如果有什么地方不懂的,可以加V:GZWjhsmart ,大家一起学习,一起进步。
更多推荐
已为社区贡献11条内容
所有评论(0)