加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
app.vue 5.37 KB
一键复制 编辑 原始数据 按行查看 历史
ferret 提交于 2024-04-11 15:09 . feat:新增无感指纹登录
<script lang="ts" setup>
import { debounce } from "~/middleware/debounce";
import navVue from "~/layout/nav.vue";
import { useAppStore } from "~/store/appStore";
import "@varlet/ui/es/Snackbar/style/index";
import "@varlet/ui/es/Dialog/style/index";
import { addViews } from "./api/public";
import { getFingerPrint } from "./utils";
import { loginByFinger } from "./api/auth";
import { Snackbar } from "@varlet/ui";
process.server && addViews();
// 生成用户指纹,使用指纹自动登录
const appStore = useAppStore();
const router = useRouter();
const { closeNav } = toRefs(appStore);
const loading = ref(false);
router.beforeEach(() => {
loading.value = true;
});
router.afterEach(() => {
loading.value = false;
});
const isHorizontal = ref(true);
function toutch(container: HTMLElement) {
let startPoint = { x: 0, y: 0 };
function touchStart(e: TouchEvent) {
const touch = e.touches[0];
startPoint = { x: touch.clientX, y: touch.clientY };
}
function touchEnd(e: TouchEvent) {
const touch = e.changedTouches[0];
const offsetX = touch.clientX - startPoint.x;
if (offsetX > 100) {
closeNav.value = false;
} else {
container.style.transform = "translateX(0)";
}
}
function touchMove(e: TouchEvent) {
const touch = e.touches[0];
// 计算滑动距离
const offsetX = touch.clientX - startPoint.x;
container.style.transform = `translateX(${offsetX}px)`;
}
return {
startPoint,
touchStart,
touchEnd,
touchMove,
};
}
/**
* @description 初始化左滑打开侧栏
*/
function initContainer() {
const container = document.querySelector("#appContainer") as HTMLElement;
if (!(container instanceof HTMLElement)) return;
let startPoint = { x: 0, y: 0 };
function touchStart(e: TouchEvent) {
const touch = e.touches[0];
startPoint = { x: touch.clientX, y: touch.clientY };
container.addEventListener("touchend", touchEnd);
container.addEventListener("touchmove", touchMove);
}
function touchEnd(e: TouchEvent) {
const touch = e.changedTouches[0];
const offsetX = touch.clientX - startPoint.x;
if (offsetX > 100) {
closeNav.value = true;
}
if (offsetX < 0) return;
container
.animate(
[
{ transform: `translateX(${offsetX}px)` },
{ transform: "translateX(0)" },
],
{
duration: 300,
easing: "ease-in-out",
}
)
.finished.then(() => {
container.style.transform = "translateX(0)";
});
container.removeEventListener("touchmove", touchMove);
container.removeEventListener("touchend", touchEnd);
}
function touchMove(e: TouchEvent) {
const touch = e.touches[0];
// 计算滑动距离
const offsetX = touch.clientX - startPoint.x;
const offsetY = touch.clientY - startPoint.y;
if (Math.abs(offsetY) > Math.abs(offsetX)) {
container.removeEventListener("touchmove", touchMove);
container.removeEventListener("touchend", touchEnd);
return;
}
container.style.transform = `translateX(${offsetX}px)`;
}
container.addEventListener("touchstart", touchStart);
}
/**
* @description 使用指纹自动登录
*/
function autoLoginByFinger() {
getFingerPrint()
.then((finger) => loginByFinger(finger))
.then((data) => {
const { token, expireTime } = data ?? {};
if (!token || !expireTime) {
return;
}
appStore.setToken(token, expireTime);
Snackbar.success("自动登录成功");
})
.catch(() => {
console.error("自动登录失败");
});
}
function showOpenManuAnimate() {
const container = document.querySelector("#appContainer") as HTMLElement;
if (!(container instanceof HTMLElement)) return;
container.animate(
[
{ transform: `translateX(0)` },
{ transform: "translateX(20%)" },
{
transform: "translateX(5%)",
},
{
transform: "translateX(20em)",
},
],
{
duration: 2000,
easing: "ease-in-out",
}
).onfinish = () => {
Snackbar.info("向右滑动可打开侧栏");
closeNav.value = true;
};
}
function init() {
if (isHorizontal.value) return;
const closeNav = localStorage.getItem("closeNav");
if (!closeNav) {
localStorage.setItem("closeNav", "true");
showOpenManuAnimate();
}
initContainer();
}
onMounted(() => {
appStore.loadGoods();
// autoLoginByFinger();
if (window.innerWidth < window.innerHeight) {
isHorizontal.value = false;
}
window.onresize = debounce(() => {
if (window.innerWidth < window.innerHeight) {
isHorizontal.value = false;
return;
}
isHorizontal.value = true;
init();
}, 500);
init();
});
</script>
<template>
<div
class="appBody"
:style="{
transform:
closeNav || isHorizontal ? 'translateX(0)' : 'translateX(-20em)',
}"
>
<navVue style="z-index: 9999"></navVue>
<main id="appContainer">
<var-overlay
@touchstart="closeNav = !closeNav"
:show="closeNav"
teleport="#appContainer"
></var-overlay>
<NuxtPage />
</main>
</div>
</template>
<style lang="less" scoped>
@import url("/assets/css/screen.less");
.appBody {
display: flex;
width: 100vw;
height: 100vh;
overflow: hidden;
transition: transform 0.2s ease-in-out;
main {
width: calc(100% - 20em);
}
.media({
width: calc(100vw + 20em);
height: 100vh;
},phone);
}
</style>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化