vue3的web实现一个锁屏的功能
  oIa1edJoFmXP 2023年12月10日 22 0


先说重点,一般这里锁屏这里放到了2个位置,一个是放到router-view和他同级,一个是用documount来实现放到对应的位置。

<template>
    <div id="app">
        <app-navbar v-if="!lockStatus"></app-navbar>
        <router-view  v-if="!lockStatus"></router-view>
        <lock-screen :show-lock="lockStatus"></lock-screen>
    </div>
</template>

vue3的web实现一个锁屏的功能_ci

<template>
    <div id="app">
        <router-view />
        <lock-screen v-if="showLockScreen" @unlock="onlock" />
    </div>
</template>

上面这种就是放到了router-view,还有一种就是

vue3的web实现一个锁屏的功能_ci_02

import LockScreenComponent from "./LockScreen.vue";
import { createApp, watch } from "vue";
const LockScreen = options => {
	const LockScreenApp = createApp(LockScreenComponent, options);
	showLockScreen(LockScreenApp);
};
const showLockScreen = app => {
	const oFragment = document.createDocumentFragment();
	const vm = app.mount(oFragment);
	document.body.appendChild(oFragment);
	vm.setVisible(true);
	watch(vm.state, state => {
		if (!state.visible) {
			hideMessageBox(app);
		}
	});
};
const hideMessageBox = app => {
	app.unmount();
};
export default LockScreen;


一个完整的例子

vue3的web实现一个锁屏的功能_ide_03

index.js

import LockScreen from "./src/index";

export { LockScreen };

src/index.js

import LockScreenComponent from "./LockScreen.vue";
import { createApp, watch } from "vue";
const LockScreen = options => {
	const LockScreenApp = createApp(LockScreenComponent, options);
	showLockScreen(LockScreenApp);
};
const showLockScreen = app => {
	const oFragment = document.createDocumentFragment();
	const vm = app.mount(oFragment);
	document.body.appendChild(oFragment);
	vm.setVisible(true);
	watch(vm.state, state => {
		if (!state.visible) {
			hideMessageBox(app);
		}
	});
};
const hideMessageBox = app => {
	app.unmount();
};
export default LockScreen;

 src/LockScreen.vue

<template>
	<transition name="messagebox-fade">
		<div v-show="visible" class="messageBox-box">
			<div class="lockscreen-item">
				<div class="loc-date">
					{{ date }}
				</div>
				<div class="loc-week">
					{{ week }}
				</div>
				<div class="loc-time">
					{{ time }}
				</div>
				<div class="loc-input">
					<input type="text" v-model="state.lockValue" />
				</div>
				<div class="loc-btn">
					<el-button type="primary" @click="cancalBtnClick">解锁</el-button>
				</div>
			</div>
		</div>
	</transition>
</template>
<script setup>
import { reactive, toRefs, onMounted, ref } from "vue";
import { getTime } from "@/utils/util";
import { ElMessage } from "element-plus";

const state = reactive({
	visible: false,
	promptValue: "",
	type: "",
	lockValue: ""
});
const { visible } = toRefs(state);
const setVisible = isVisible => {
	state.visible = isVisible;
};
const cancalBtnClick = () => {
	let item = localStorage.getItem("lockScreen");
	if (item === state.lockValue) {
		localStorage.removeItem("lockScreen");
		setVisible(false);
	} else {
		return ElMessage.error("密码错误");
	}
};
defineExpose({
	setVisible,
	state
});
const date = ref("loading..");
const time = ref("loading..");
const week = ref("loading..");
onMounted(() => {
	setInterval(() => {
		date.value = getTime(1);
		time.value = getTime(2);
		week.value = getTime(3);
	}, 1000);
});
</script>
<style lang="scss" scoped>
.messagebox-fade-enter-from,
.messagebox-fade-leave-to {
	opacity: 0;
}
.messagebox-fade-enter-active {
	transition: opacity 0.2s ease-in;
}
.messagebox-fade-leave-active {
	transition: opacity 0.2s ease-out;
}
.messageBox-box {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: #000;
	display: flex;
	justify-content: center;
	// align-items: center;
	z-index: 2000;
	animation: identifier 0.8s;
	@keyframes identifier {
		0% {
			margin-left: 100vw;
		}
		100% {
			margin-top: 0;
		}
	}
	.lockscreen-item {
		color: #fff;
		text-align: center;
	}

	.loc-date {
		text-align: center;
		font-size: 30px;
		margin-top: 50px;
	}
	.loc-week {
		text-align: center;
		font-size: 30px;
		margin-top: 10px;
	}
	.loc-time {
		font-size: 80px;
		font-weight: bold;
		margin-top: 10px;
	}
	.loc-input {
		margin-top: 10px;
		input {
			margin: 40px 0;
			box-sizing: border-box;
			font-variant: tabular-nums;
			list-style: none;
			font-feature-settings: tnum;
			position: relative;
			display: inline-block;
			width: 100%;
			padding: 4px 11px;
			color: #000000d9;
			font-size: 14px;
			line-height: 1.5715;
			background-color: #fff;
			background-image: none;
			border: 1px solid #d9d9d9;
			border-radius: 2px;
			transition: all 0.3s;
			outline: none;
		}
	}
}
</style>

触发上面的锁组件

这个layout中的组件中有个来触发锁屏的组件

<template>
	<img src="@/assets/svg/suotou.svg" @click="handleLockScreen" style="width: 25x; height: 25px; cursor: pointer" />
</template>
<script setup>
import { onMounted } from "vue";
import { MessageBox } from "@/components/MessageBox";
import { LockScreen } from "@/components/LockScreen";
//  锁屏
const handleLockScreen = () => {
	MessageBox.prompt({
		confirmBtnText: "锁屏",
		title: "请输入锁屏密码"
	})
		.then(value => {
			if (!value)
				return ElMessage({
					message: "请输入",
					type: "warning"
				});
			localStorage.setItem("lockScreen", value);
			LockScreen();
		})
		.catch(() => {
			console.log("取消");
		});
};

onMounted(() => {
	let lock = localStorage.getItem("lockScreen") || "";
	if (lock) {
		LockScreen();
	}
});
</script>

vue3的web实现一个锁屏的功能_ide_04




另一种常见的完整例子

创建一个LockScreen.vue的组件,该组件包含一个输入框和按钮,用于验证锁屏密码。

<template>
  <div class="lock-screen-container">
  <input type="password" v-model="password" placeholder="请输入密码" />
  <button @click="unlock">解锁</button>
</template>

<script>
export default {
  data() {
    return {
      password: ''
    }
  },
  methods: {
    unlock() {
      if (this.password === '{你设置的密码}') {
        this.$emit('unlock'); //发送解锁事件
      } else {
        alert("密码错误");
      }
    }
  }

}
</script>

<style scoped>
.lock-screen-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>

在App.vue中引入LockScreen组件,并使用v-if控制其显示和隐藏。

<template>
  <div id="app">
    <router-view />
    <LockScreen v-if="showLockScreen" @unlock="unlock" />
  </div>
</template>

<script>
import LockScreen from './components/LockScreen.vue';

export default {
  data() {
    return {
      showLockScreen: false;
      locked: false;
    }
  },
  methods: {
    lock() {
      this.showLockScreen = true;
      this.locked = true;
    }
    unlock() {
      this.showLockScreen = false;
      this.locked = true;
    }
  },
  mounted() {
    //监听页面是否出狱活动状态
    document.addEventListener('visibilitychange', ()=>{
      if (document.hidden && !this.locked) {
        this.lock();
      }
    });
  }
}
</script>

<style scoped>
.lock-screen-container {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
}
</style>


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月10日 0

暂无评论

推荐阅读
  jnZtF7Co41Wg   2023年11月24日   21   0   0 分区表cicentos
  YKMEHzdP8aoh   2023年12月11日   43   0   0 DNSidePod
  YKMEHzdP8aoh   2023年11月24日   15   0   0 ide重定向Rust
oIa1edJoFmXP