vue实现封锁页面
Vue 实现页面封锁的方法
在 Vue 中实现页面封锁通常用于阻止用户在某些操作未完成或权限不足时访问特定内容。以下是几种常见实现方式:
使用全局路由守卫
通过 Vue Router 的导航守卫拦截未授权访问:
// router.js
router.beforeEach((to, from, next) => {
const isLocked = store.getters.isPageLocked // 从Vuex获取锁定状态
if (to.meta.requiresUnlock && isLocked) {
next('/locked-page') // 跳转到锁定提示页
} else {
next()
}
})
路由配置需添加元信息:
{
path: '/protected',
component: ProtectedPage,
meta: { requiresUnlock: true }
}
组件级条件渲染
在组件内部通过 v-if 控制内容显示:
<template>
<div>
<div v-if="!isLocked">
<!-- 正常内容 -->
</div>
<lock-screen v-else />
</div>
</template>
<script>
export default {
computed: {
isLocked() {
return this.$store.state.isLocked
}
}
}
</script>
全局遮罩层组件
创建可复用的锁屏组件:
<!-- LockScreen.vue -->
<template>
<div class="lock-screen">
<div class="overlay"></div>
<div class="content">
<h3>操作受限</h3>
<p>当前页面已被锁定,请完成前置操作</p>
<button @click="handleUnlock">解锁</button>
</div>
</div>
</template>
<style>
.lock-screen {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
}
.overlay {
background: rgba(0,0,0,0.7);
position: absolute;
width: 100%;
height: 100%;
}
.content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 2rem;
border-radius: 8px;
}
</style>
状态管理集成
通过 Vuex 集中管理锁定状态:
// store.js
export default new Vuex.Store({
state: {
lockedPages: []
},
mutations: {
lockPage(state, pageName) {
if (!state.lockedPages.includes(pageName)) {
state.lockedPages.push(pageName)
}
},
unlockPage(state, pageName) {
state.lockedPages = state.lockedPages.filter(p => p !== pageName)
}
}
})
浏览器事件拦截
阻止默认行为增强锁定效果:
mounted() {
if (this.isLocked) {
window.addEventListener('keydown', this.preventNavigation)
window.addEventListener('beforeunload', this.confirmUnload)
}
},
methods: {
preventNavigation(e) {
if ([8, 116].includes(e.keyCode)) { // 阻止后退和刷新
e.preventDefault()
}
},
confirmUnload(e) {
e.preventDefault()
return e.returnValue = '离开后未保存的数据将丢失'
}
}
注意事项
- 敏感操作建议结合后端验证,前端封锁仅作为辅助
- 清除锁定状态时需同步移除事件监听
- 移动端需额外考虑 touch 事件拦截
- 提供清晰的解锁指引给用户
以上方法可根据实际需求组合使用,建议通过 Vuex 集中管理锁定状态以保证应用状态一致性。







