feat(custom): 新增登录页面样式

This commit is contained in:
nongyehong 2024-01-17 02:50:48 +08:00
parent be6bc2dde7
commit 8f0d27e2bd
14 changed files with 296 additions and 35 deletions

View File

@ -5,6 +5,9 @@
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri + Vue + TS</title>
<!--引入iconpark图标库-->
<script defer src="https://lf1-cdn-tos.bytegoofy.com/obj/iconpark/svg_30895_2.9296a4fe95142450c1ca2d8b8ecbb059.js"></script>
</head>
<body>

View File

@ -47,7 +47,7 @@
"label": "login",
"url": "/login",
"fullscreen": false,
"resizable": true,
"resizable": false,
"center": true,
"width": 320,
"height": 448,

View File

@ -34,6 +34,14 @@ import { storeToRefs } from 'pinia'
// const choose3 = ref('')
const themeStore = theme()
const { BGC } = storeToRefs(themeStore)
onMounted(() => {
// window.addEventListener('contextmenu', (e) => e.preventDefault(), false)
})
onUnmounted(() => {
window.removeEventListener('contextmenu', (e) => e.preventDefault(), false)
})
</script>
<style scoped>
#app {

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1705374413909" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7701" xmlns:xlink="http://www.w3.org/1999/xlink" width="48" height="48"><path d="M143.616 47.104l830.08 830.08c26.24 26.24 26.24 69.888 0 96.128-26.24 26.24-69.888 26.24-96.128 0L47.488 143.232c-17.536-26.24-17.536-69.888 0-96.128 26.24-26.24 69.888-26.24 96.128 0z m0 0" fill="#ffffff" p-id="7702"></path><path d="M982.528 143.232L152.32 973.312c-26.24 26.24-69.888 26.24-96.128 0-26.24-26.24-26.24-69.888 0-96.128L886.4 47.104c26.24-26.24 69.888-26.24 96.128 0 17.408 26.24 17.408 69.888 0 96.128z m0 0" fill="#ffffff" p-id="7703"></path></svg>

After

Width:  |  Height:  |  Size: 796 B

1
src/assets/svg/close.svg Normal file
View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1705372642705" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7402" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M143.616 47.104l830.08 830.08c26.24 26.24 26.24 69.888 0 96.128-26.24 26.24-69.888 26.24-96.128 0L47.488 143.232c-17.536-26.24-17.536-69.888 0-96.128 26.24-26.24 69.888-26.24 96.128 0z m0 0" fill="#707070" p-id="7403"></path><path d="M982.528 143.232L152.32 973.312c-26.24 26.24-69.888 26.24-96.128 0-26.24-26.24-26.24-69.888 0-96.128L886.4 47.104c26.24-26.24 69.888-26.24 96.128 0 17.408 26.24 17.408 69.888 0 96.128z m0 0" fill="#707070" p-id="7404"></path></svg>

After

Width:  |  Height:  |  Size: 796 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1705372525309" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4104" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M812.3 959.4H213.7c-81.6 0-148-66.4-148-148V212.9c0-81.6 66.4-148 148-148h598.5c81.6 0 148 66.4 148 148v598.5C960.3 893 893.9 959.4 812.3 959.4zM213.7 120.9c-50.7 0-92 41.3-92 92v598.5c0 50.7 41.3 92 92 92h598.5c50.7 0 92-41.3 92-92V212.9c0-50.7-41.3-92-92-92H213.7z" fill="#707070" p-id="4105"></path></svg>

After

Width:  |  Height:  |  Size: 639 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1705372596720" class="icon" viewBox="0 0 7168 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6186" width="336" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M4441.95120779 617.62257531h-1760.37625529c-56.33204017 0-105.62257531-49.29053514-105.62257532-105.62257531s49.29053514-105.62257531 105.62257532-105.62257531h1760.37625529c56.33204017 0 105.62257531 49.29053514 105.62257533 105.62257531s-49.29053514 105.62257531-105.62257533 105.62257531z" p-id="6187" fill="#707070"></path></svg>

After

Width:  |  Height:  |  Size: 665 B

View File

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1705375072061" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10477" width="48" height="48" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M959.720175 0H294.216115a63.960025 63.960025 0 0 0-63.960025 63.960025v127.92005H64.279825a63.960025 63.960025 0 0 0-63.960025 63.960025v703.560275a63.960025 63.960025 0 0 0 63.960025 63.960025h703.560275a63.960025 63.960025 0 0 0 63.960025-63.960025v-166.935665h127.92005a63.960025 63.960025 0 0 0 63.960025-63.960025V63.960025a63.960025 63.960025 0 0 0-63.960025-63.960025z m-191.880075 728.504685V959.400375H64.279825V255.8401h703.560275z m189.321674 0H831.800125V255.8401a63.960025 63.960025 0 0 0-63.960025-63.960025H294.216115V63.960025H959.720175z" fill="#707070" p-id="10478"></path></svg>

After

Width:  |  Height:  |  Size: 929 B

35
src/common/WindowEvent.ts Normal file
View File

@ -0,0 +1,35 @@
import { appWindow, WebviewWindow } from '@tauri-apps/api/window'
/** 最小化 */
export const minimizeWindow = async () => {
await appWindow.minimize()
}
/** 最大化 */
export const maximizeWindow = async () => {
await appWindow.maximize()
}
/** 关闭 */
export const closeWindow = async () => {
await appWindow.close()
}
/** 取消最大化 */
export const unmaximize = async () => {
await appWindow.unmaximize()
}
/** 隐藏 */
export const hideWindow = async () => {
await appWindow.hide()
}
/**
*
* @param label
* */
export const autoCloseWindow = async (label: string) => {
const win = WebviewWindow.getByLabel(label)
await win?.close()
}

View File

@ -38,13 +38,13 @@ watchEffect(() => {
/*调整naive ui的primary的主题颜色和样式*/
const themeOverrides: GlobalThemeOverrides = {
Input: {
borderRadius: '6px'
borderRadius: '10px'
},
Tag: {
borderRadius: '4px'
},
Button: {
borderRadiusMedium: '6px'
borderRadiusMedium: '10px'
}
}

View File

@ -0,0 +1,71 @@
<template>
<div data-tauri-drag-region class="flex justify-end">
<!-- 最小化 -->
<div @click="minimizeWindow" class="w-28px h24px flex-center hover:bg-#e7e7e7">
<img src="@/assets/svg/minimize.svg" class="w-38px h-34px" alt="" />
</div>
<!-- 最大化 -->
<div @click="restoreWindow" class="w-28px h24px flex-center hover:bg-#e7e7e7">
<img v-show="!windowMaximized" src="@/assets/svg/maximize.svg" class="w-14px h-14px" alt="" />
<img v-show="windowMaximized" src="@/assets/svg/normal.svg" class="w-14px h-14px" alt="" />
</div>
<!-- 关闭窗口 -->
<div @click="closeWindow" class="close-box w-28px h24px flex-center cursor-pointer hover:bg-#c22b1c rounded-tr-6px">
<img src="@/assets/svg/close.svg" class="default-img w-10px h-10px" alt="" />
<img src="@/assets/svg/close-hover.svg" class="hover-img w-10px h-10px" alt="" />
</div>
</div>
</template>
<script setup lang="ts">
import { closeWindow, maximizeWindow, minimizeWindow, unmaximize } from '@/common/WindowEvent.ts'
import { appWindow } from '@tauri-apps/api/window'
const windowMaximized = ref(false)
// // unlisten
// let unlistenMoveEvent = null as any
//
// watchEffect(async () => {
// if (windowMaximized.value) {
// unlistenMoveEvent = await appWindow.listen('tauri://move', () => {
// windowMaximized.value = false
// unlistenMoveEvent()
// unlistenMoveEvent = null
// })
// }
// })
/* 判断当前是否是最大化窗口 */
const checkMaximizedStatus = async () => {
windowMaximized.value = await appWindow.isMaximized()
}
/* 恢复窗口大小 */
const restoreWindow = async () => {
if (windowMaximized.value) {
await unmaximize()
} else {
await maximizeWindow()
}
await checkMaximizedStatus()
}
</script>
<style scoped lang="scss">
/* 当鼠标悬停在按钮上时,切换显示状态 */
.close-box {
/* 默认不显示 */
.hover-img {
display: none;
}
&:hover {
.default-img {
display: none;
}
.hover-img {
display: block;
}
}
}
</style>

View File

@ -1,9 +1,39 @@
<template>
<div
class="w-60px bg-#AA5757FF h-full pt-10px pl-8px pr-8px pb-10px box-border flex justify-center rounded-tl-8px rounded-bl-8px">
<img class="border-rounded-50% bg-#000 w-34px h-34px" src="" alt="" />
class="w-60px bg-#AA5757FF h-full pt-10px pl-8px pr-8px pb-10px box-border flex-x-center rounded-tl-8px rounded-bl-8px">
<img
@click="toLogin"
class="border-rounded-50% w-34px h-34px bg-#f1f1f1 cursor-pointer"
style="border: 1px solid #fff"
src="/logo.png"
alt="" />
</div>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { WebviewWindow } from '@tauri-apps/api/window'
import { autoCloseWindow } from '@/common/WindowEvent.ts'
const toLogin = async () => {
// todo 使
const webview = new WebviewWindow('login', {
url: '/login',
fullscreen: false,
resizable: false,
center: true,
width: 320,
height: 448,
skipTaskbar: false,
decorations: false,
transparent: true
})
await webview.once('tauri://created', function () {
console.log('创建成功')
autoCloseWindow('home')
})
await webview.once('tauri://error', function (e) {
console.log(e)
})
}
</script>
<style scoped></style>

View File

@ -1,23 +1,6 @@
<template>
<div class="flex-1 bg-[#f1f1f1ff] h-full rounded-tr-8px rounded-br-8px w-100vw">
<div data-tauri-drag-region class="flex justify-end">
<div
id="titlebar-close"
class="w-28px h24px flex-center cursor-pointer color-#606060 hover:bg-#c22b1c hover:color-#fff rounded-tr-6px">
X
</div>
</div>
<ActionBar />
</div>
</template>
<script setup lang="ts">
import { appWindow } from '@tauri-apps/api/window'
onMounted(() => {
// document.getElementById('titlebar-minimize')!.addEventListener('click', () => appWindow.minimize())
// document.getElementById('titlebar-maximize')!.addEventListener('click', () => appWindow.toggleMaximize())
document.getElementById('titlebar-close')!.addEventListener('click', () => appWindow.close())
console.log('onMounted------', document.getElementById('titlebar-close'))
})
</script>
<style scoped></style>
<script setup lang="ts"></script>

View File

@ -1,18 +1,114 @@
<template>
<div class="flex-center h-full">
<n-button @click="loginWin" secondary type="primary">登录</n-button>
<div class="bg-#f1f1f1 wh-full rounded-8px">
<!--顶部操作栏-->
<div data-tauri-drag-region class="w-full flex justify-end">
<!-- 最小化 -->
<div @click="minimizeWindow" class="w-28px h24px flex-center hover:bg-#e7e7e7">
<img src="@/assets/svg/minimize.svg" class="w-38px h-34px" alt="" />
</div>
<!-- 关闭窗口 -->
<div
@click="closeWindow"
class="close-box w-28px h24px flex-center cursor-pointer hover:bg-#c22b1c rounded-tr-6px">
<img src="@/assets/svg/close.svg" class="default-img w-10px h-10px" alt="" />
<img src="@/assets/svg/close-hover.svg" class="hover-img w-10px h-10px" alt="" />
</div>
</div>
<!-- 头像 -->
<div class="w-full flex-x-center mt-35px mb-25px">
<img style="border: 2px solid #fff" class="w-80px h-80px rounded-50%" src="/logo.png" alt="" />
</div>
<!-- 登录菜单 -->
<n-flex class="ma text-center h-full w-260px" vertical :size="16">
<n-input
style="padding-left: 20px"
size="large"
maxlength="16"
minlength="6"
v-model:value="account"
type="text"
:placeholder="accountPH"
@focus="accountPH = ''"
@blur="accountPH = '输入HuLa账号'"
clearable>
<template #suffix>
<!--todo 可以参考yao3的关于下拉框-->
<svg class="w-18px h-18px color-#505050 cursor-pointer"><use href="#down-bojg611f"></use></svg>
</template>
</n-input>
<n-input
maxlength="16"
minlength="6"
size="large"
v-model:value="password"
type="password"
:placeholder="passwordPH"
@focus="passwordPH = ''"
@blur="passwordPH = '输入HuLa密码'"
clearable />
<!-- 协议 -->
<n-flex justify="center" :size="6">
<n-checkbox v-model:checked="protocol" />
<div class="font-size-12px color-#909090 cursor-default lh-14px">
<span>已阅读并同意</span>
<span class="color-#189f57 cursor-pointer">服务协议</span>
<span></span>
<span class="color-#189f57 cursor-pointer">HuLa隐私保护指引</span>
</div>
</n-flex>
<n-button
:loading="loading"
:disabled="loginDisabled"
class="w-full mt-10px mb-35px"
@click="loginWin"
type="primary">
登录
</n-button>
<!-- 顶部操作栏 -->
<n-flex justify="center" class="font-size-14px">
<div class="color-#189f57 cursor-pointer">扫码登录</div>
<div class="w-1px h-14px bg-#ccc"></div>
<n-popover style="padding: 6px; border-radius: 8px" trigger="click" :show-checkmark="false" :show-arrow="false">
<template #trigger>
<div class="color-#189f57 cursor-pointer">更多选项</div>
</template>
<n-flex vertical :size="2">
<div class="font-size-14px cursor-pointer hover:bg-#f3f3f3 hover:rounded-6px p-8px font-size-12px">
注册账号
</div>
<div class="font-size-14px cursor-pointer hover:bg-#f3f3f3 hover:rounded-6px p-8px font-size-12px">
忘记密码
</div>
</n-flex>
</n-popover>
</n-flex>
</n-flex>
</div>
</template>
<script setup lang="ts">
import { WebviewWindow } from '@tauri-apps/api/window'
import { closeWindow, autoCloseWindow, minimizeWindow } from '@/common/WindowEvent.ts'
let close = (label: string) => {
const win = WebviewWindow.getByLabel(label)
win?.close()
}
const account = ref()
const password = ref()
const protocol = ref()
const loginDisabled = ref(false)
const loading = ref(false)
const accountPH = ref('输入HuLa账号')
const passwordPH = ref('输入HuLa密码')
let loginWin = async () => {
const webview = new WebviewWindow('page', {
watchEffect(() => {
loginDisabled.value = !(account.value && password.value && protocol.value)
})
const loginWin = async () => {
loading.value = true
const webview = new WebviewWindow('home', {
url: '/',
fullscreen: false,
resizable: true,
@ -25,12 +121,42 @@ let loginWin = async () => {
})
await webview.once('tauri://created', function () {
console.log('创建成功')
close('login')
autoCloseWindow('login')
loading.value = false
})
await webview.once('tauri://error', function (e) {
console.log(e)
loading.value = false
})
}
</script>
<style scoped></style>
<style scoped lang="scss">
/* 当鼠标悬停在按钮上时,切换显示状态 */
.close-box {
/* 默认不显示 */
.hover-img {
display: none;
}
&:hover {
.default-img {
display: none;
}
.hover-img {
display: block;
}
}
}
/* 改变输入框中的位置 */
:deep(.n-input .n-input__input, .n-input .n-input__textarea) {
margin-left: 22px;
}
/* 修改复选框的样式 */
:deep(.n-checkbox .n-checkbox-box) {
border-radius: 50%;
width: 16px;
height: 16px;
}
</style>