feat: 去除tailwindcss

This commit is contained in:
2026-06-17 11:55:13 +08:00
parent 09221c819a
commit dedf172539
12 changed files with 363 additions and 292 deletions

6
components.d.ts vendored
View File

@@ -17,20 +17,17 @@ declare module 'vue' {
IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default']
IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default']
NAvatar: typeof import('naive-ui')['NAvatar']
NButton: typeof import('naive-ui')['NButton']
NCheckbox: typeof import('naive-ui')['NCheckbox']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NForm: typeof import('naive-ui')['NForm']
NFormItem: typeof import('naive-ui')['NFormItem']
NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
NInput: typeof import('naive-ui')['NInput']
NInputOtp: typeof import('naive-ui')['NInputOtp']
NMessageProvider: typeof import('naive-ui')['NMessageProvider']
NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
NQrCode: typeof import('naive-ui')['NQrCode']
NSpace: typeof import('naive-ui')['NSpace']
NThemeEditor: typeof import('naive-ui')['NThemeEditor']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}
@@ -43,20 +40,17 @@ declare global {
const IconEcosystem: typeof import('./src/components/icons/IconEcosystem.vue')['default']
const IconSupport: typeof import('./src/components/icons/IconSupport.vue')['default']
const IconTooling: typeof import('./src/components/icons/IconTooling.vue')['default']
const NAvatar: typeof import('naive-ui')['NAvatar']
const NButton: typeof import('naive-ui')['NButton']
const NCheckbox: typeof import('naive-ui')['NCheckbox']
const NConfigProvider: typeof import('naive-ui')['NConfigProvider']
const NForm: typeof import('naive-ui')['NForm']
const NFormItem: typeof import('naive-ui')['NFormItem']
const NGlobalStyle: typeof import('naive-ui')['NGlobalStyle']
const NInput: typeof import('naive-ui')['NInput']
const NInputOtp: typeof import('naive-ui')['NInputOtp']
const NMessageProvider: typeof import('naive-ui')['NMessageProvider']
const NNotificationProvider: typeof import('naive-ui')['NNotificationProvider']
const NQrCode: typeof import('naive-ui')['NQrCode']
const NSpace: typeof import('naive-ui')['NSpace']
const NThemeEditor: typeof import('naive-ui')['NThemeEditor']
const RouterLink: typeof import('vue-router')['RouterLink']
const RouterView: typeof import('vue-router')['RouterView']
}

View File

@@ -20,7 +20,6 @@
"vue-router": "^5.0.4"
},
"devDependencies": {
"@tailwindcss/vite": "^4.3.0",
"@tsconfig/node24": "^24.0.4",
"@types/node": "^24.12.2",
"@vitejs/plugin-vue": "^6.0.6",
@@ -29,7 +28,6 @@
"npm-run-all2": "^8.0.4",
"oxfmt": "^0.45.0",
"sass-embedded": "^1.100.0",
"tailwindcss": "^4.3.0",
"typescript": "~6.0.0",
"unplugin-auto-import": "^21.0.0",
"unplugin-vue-components": "^32.1.0",

196
pnpm-lock.yaml generated
View File

@@ -27,9 +27,6 @@ importers:
specifier: ^5.0.4
version: 5.1.0(@vue/compiler-sfc@3.5.35)(pinia@3.0.4(typescript@6.0.3)(vue@3.5.35(typescript@6.0.3)))(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))(vue@3.5.35(typescript@6.0.3))
devDependencies:
'@tailwindcss/vite':
specifier: ^4.3.0
version: 4.3.0(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))
'@tsconfig/node24':
specifier: ^24.0.4
version: 24.0.4
@@ -54,9 +51,6 @@ importers:
sass-embedded:
specifier: ^1.100.0
version: 1.100.0
tailwindcss:
specifier: ^4.3.0
version: 4.3.0
typescript:
specifier: ~6.0.0
version: 6.0.3
@@ -603,100 +597,6 @@ packages:
'@rolldown/pluginutils@1.0.1':
resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==}
'@tailwindcss/node@4.3.0':
resolution: {integrity: sha512-aFb4gUhFOgdh9AXo4IzBEOzBkkAxm9VigwDJnMIYv3lcfXCJVesNfbEaBl4BNgVRyid92AmdviqwBUBRKSeY3g==}
'@tailwindcss/oxide-android-arm64@4.3.0':
resolution: {integrity: sha512-TJPiq67tKlLuObP6RkwvVGDoxCMBVtDgKkLfa/uyj7/FyxvQwHS+UOnVrXXgbEsfUaMgiVvC4KbJnRr26ho4Ng==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [android]
'@tailwindcss/oxide-darwin-arm64@4.3.0':
resolution: {integrity: sha512-oMN/WZRb+SO37BmUElEgeEWuU8E/HXRkiODxJxLe1UTHVXLrdVSgfaJV7pSlhRGMSOiXLuxTIjfsF3wYvz8cgQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [darwin]
'@tailwindcss/oxide-darwin-x64@4.3.0':
resolution: {integrity: sha512-N6CUmu4a6bKVADfw77p+iw6Yd9Q3OBhe0veaDX+QazfuVYlQsHfDgxBrsjQ/IW+zywL8mTrNd0SdJT/zgtvMdA==}
engines: {node: '>= 20'}
cpu: [x64]
os: [darwin]
'@tailwindcss/oxide-freebsd-x64@4.3.0':
resolution: {integrity: sha512-zDL5hBkQdH5C6MpqbK3gQAgP80tsMwSI26vjOzjJtNCMUo0lFgOItzHKBIupOZNQxt3ouPH7RPhvNhiTfCe5CQ==}
engines: {node: '>= 20'}
cpu: [x64]
os: [freebsd]
'@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0':
resolution: {integrity: sha512-R06HdNi7A7OEoMsf6d4tjZ71RCWnZQPHj2mnotSFURjNLdBC+cIgXQ7l81CqeoiQftjf6OOblxXMInMgN2VzMA==}
engines: {node: '>= 20'}
cpu: [arm]
os: [linux]
'@tailwindcss/oxide-linux-arm64-gnu@4.3.0':
resolution: {integrity: sha512-qTJHELX8jetjhRQHCLilkVLmybpzNQAtaI/gaoVoidn/ufbNDbAo8KlK2J+yPoc8wQxvDxCmh/5lr8nC1+lTbg==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
libc: [glibc]
'@tailwindcss/oxide-linux-arm64-musl@4.3.0':
resolution: {integrity: sha512-Z6sukiQsngnWO+l39X4pPbiWT81IC+PLKF+PHxIlyZbGNb9MODfYlXEVlFvej5BOZInWX01kVyzeLvHsXhfczQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [linux]
libc: [musl]
'@tailwindcss/oxide-linux-x64-gnu@4.3.0':
resolution: {integrity: sha512-DRNdQRpSGzRGfARVuVkxvM8Q12nh19l4BF/G7zGA1oe+9wcC6saFBHTISrpIcKzhiXtSrlSrluCfvMuledoCTQ==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
libc: [glibc]
'@tailwindcss/oxide-linux-x64-musl@4.3.0':
resolution: {integrity: sha512-Z0IADbDo8bh6I7h2IQMx601AdXBLfFpEdUotft86evd/8ZPflZe9COPO8Q1vw+pfLWIUo9zN/JGZvwuAJqduqg==}
engines: {node: '>= 20'}
cpu: [x64]
os: [linux]
libc: [musl]
'@tailwindcss/oxide-wasm32-wasi@4.3.0':
resolution: {integrity: sha512-HNZGOUxEmElksYR7S6sC5jTeNGpobAsy9u7Gu0AskJ8/20FR9GqebUyB+HBcU/ax6BHuiuJi+Oda4B+YX6H1yA==}
engines: {node: '>=14.0.0'}
cpu: [wasm32]
bundledDependencies:
- '@napi-rs/wasm-runtime'
- '@emnapi/core'
- '@emnapi/runtime'
- '@tybys/wasm-util'
- '@emnapi/wasi-threads'
- tslib
'@tailwindcss/oxide-win32-arm64-msvc@4.3.0':
resolution: {integrity: sha512-Pe+RPVTi1T+qymuuRpcdvwSVZjnll/f7n8gBxMMh3xLTctMDKqpdfGimbMyioqtLhUYZxdJ9wGNhV7MKHvgZsQ==}
engines: {node: '>= 20'}
cpu: [arm64]
os: [win32]
'@tailwindcss/oxide-win32-x64-msvc@4.3.0':
resolution: {integrity: sha512-Mvrf2kXW/yeW/OTezZlCGOirXRcUuLIBx/5Y12BaPM7wJoryG6dfS/NJL8aBPqtTEx/Vm4T4vKzFUcKDT+TKUA==}
engines: {node: '>= 20'}
cpu: [x64]
os: [win32]
'@tailwindcss/oxide@4.3.0':
resolution: {integrity: sha512-F7HZGBeN9I0/AuuJS5PwcD8xayx5ri5GhjYUDBEVYUkexyA/giwbDNjRVrxSezE3T250OU2K/wp/ltWx3UOefg==}
engines: {node: '>= 20'}
'@tailwindcss/vite@4.3.0':
resolution: {integrity: sha512-t6J3OrB5Fc0ExuhohouH0fWUGMYL6PTLhW+E7zIk/pdbnJARZDCwjBznFnkh5ynRnIRSI4YjtTH0t6USjJISrw==}
peerDependencies:
vite: ^5.2.0 || ^6 || ^7 || ^8
'@tsconfig/node24@24.0.4':
resolution: {integrity: sha512-2A933l5P5oCbv6qSxHs7ckKwobs8BDAe9SJ/Xr2Hy+nDlwmLE1GhFh/g/vXGRZWgxBg9nX/5piDtHR9Dkw/XuA==}
@@ -996,10 +896,6 @@ packages:
electron-to-chromium@1.5.364:
resolution: {integrity: sha512-G/dYE3+AYhyHwzTwg8UbnXf7zqMERYh7l2jJ3QujhFsH8agSYwtnGAR2aZ7f0AakIKJXd5En/Hre4igIUrdlYw==}
enhanced-resolve@5.22.1:
resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==}
engines: {node: '>=10.13.0'}
entities@7.0.1:
resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==}
engines: {node: '>=0.12'}
@@ -1089,9 +985,6 @@ packages:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
has-flag@4.0.0:
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
engines: {node: '>=8'}
@@ -1624,13 +1517,6 @@ packages:
resolution: {integrity: sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==}
engines: {node: '>=16.0.0'}
tailwindcss@4.3.0:
resolution: {integrity: sha512-y6nxMGB1nMW9R6k96e5gdIFzcfL/gTJRNaqGes1YvkLnPVXzWgbqFF2yLC0T8G774n24cx3Pe8XrKoniCOAH+Q==}
tapable@2.3.3:
resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==}
engines: {node: '>=6'}
tinyglobby@0.2.17:
resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==}
engines: {node: '>=12.0.0'}
@@ -2300,74 +2186,6 @@ snapshots:
'@rolldown/pluginutils@1.0.1': {}
'@tailwindcss/node@4.3.0':
dependencies:
'@jridgewell/remapping': 2.3.5
enhanced-resolve: 5.22.1
jiti: 2.7.0
lightningcss: 1.32.0
magic-string: 0.30.21
source-map-js: 1.2.1
tailwindcss: 4.3.0
'@tailwindcss/oxide-android-arm64@4.3.0':
optional: true
'@tailwindcss/oxide-darwin-arm64@4.3.0':
optional: true
'@tailwindcss/oxide-darwin-x64@4.3.0':
optional: true
'@tailwindcss/oxide-freebsd-x64@4.3.0':
optional: true
'@tailwindcss/oxide-linux-arm-gnueabihf@4.3.0':
optional: true
'@tailwindcss/oxide-linux-arm64-gnu@4.3.0':
optional: true
'@tailwindcss/oxide-linux-arm64-musl@4.3.0':
optional: true
'@tailwindcss/oxide-linux-x64-gnu@4.3.0':
optional: true
'@tailwindcss/oxide-linux-x64-musl@4.3.0':
optional: true
'@tailwindcss/oxide-wasm32-wasi@4.3.0':
optional: true
'@tailwindcss/oxide-win32-arm64-msvc@4.3.0':
optional: true
'@tailwindcss/oxide-win32-x64-msvc@4.3.0':
optional: true
'@tailwindcss/oxide@4.3.0':
optionalDependencies:
'@tailwindcss/oxide-android-arm64': 4.3.0
'@tailwindcss/oxide-darwin-arm64': 4.3.0
'@tailwindcss/oxide-darwin-x64': 4.3.0
'@tailwindcss/oxide-freebsd-x64': 4.3.0
'@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.0
'@tailwindcss/oxide-linux-arm64-gnu': 4.3.0
'@tailwindcss/oxide-linux-arm64-musl': 4.3.0
'@tailwindcss/oxide-linux-x64-gnu': 4.3.0
'@tailwindcss/oxide-linux-x64-musl': 4.3.0
'@tailwindcss/oxide-wasm32-wasi': 4.3.0
'@tailwindcss/oxide-win32-arm64-msvc': 4.3.0
'@tailwindcss/oxide-win32-x64-msvc': 4.3.0
'@tailwindcss/vite@4.3.0(vite@8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0))':
dependencies:
'@tailwindcss/node': 4.3.0
'@tailwindcss/oxide': 4.3.0
tailwindcss: 4.3.0
vite: 8.0.16(@types/node@24.12.4)(jiti@2.7.0)(sass-embedded@1.100.0)(sass@1.100.0)(yaml@2.9.0)
'@tsconfig/node24@24.0.4': {}
'@tybys/wasm-util@0.10.2':
@@ -2725,11 +2543,6 @@ snapshots:
electron-to-chromium@1.5.364: {}
enhanced-resolve@5.22.1:
dependencies:
graceful-fs: 4.2.11
tapable: 2.3.3
entities@7.0.1: {}
error-stack-parser-es@1.0.5: {}
@@ -2804,8 +2617,6 @@ snapshots:
gopd@1.2.0: {}
graceful-fs@4.2.11: {}
has-flag@4.0.0: {}
has-symbols@1.1.0: {}
@@ -2857,7 +2668,8 @@ snapshots:
isexe@3.1.5: {}
jiti@2.7.0: {}
jiti@2.7.0:
optional: true
js-tokens@4.0.0: {}
@@ -3273,10 +3085,6 @@ snapshots:
sync-message-port@1.2.0: {}
tailwindcss@4.3.0: {}
tapable@2.3.3: {}
tinyglobby@0.2.17:
dependencies:
fdir: 6.5.0(picomatch@4.0.4)

View File

@@ -4,7 +4,7 @@
:date-locale="dateZhCN"
:theme="lightTheme"
:theme-overrides="themeOverrides"
class="h-full"
class="app-wrapper"
>
<NNotificationProvider>
<NMessageProvider>
@@ -27,3 +27,9 @@ const themeOverrides: GlobalThemeOverrides = {
}
}
</script>
<style scoped>
.app-wrapper {
height: 100%;
}
</style>

View File

@@ -1,2 +1 @@
import './tailwind.css'
import './base.css'

View File

@@ -1,14 +0,0 @@
@import 'tailwindcss';
@utility flex-center {
display: flex;
align-items: center;
justify-content: center;
}
@utility flex-col-center {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}

View File

@@ -1,24 +1,22 @@
<template>
<div class="flex min-h-lvh flex-1 overflow-x-hidden select-none">
<div class="relative flex-center w-full">
<div class="login-background absolute top-0 left-0 size-full"></div>
<div
class="flex-col-center relative bg-white rounded-3xl pb-10 px-6 py-10 md:w-2/3 lg:w-1/2 xl:w-[36%]"
>
<div class="auth-layout">
<div class="auth-layout__center">
<div class="auth-layout__bg"></div>
<div class="auth-layout__card">
<RouterView v-slot="{ Component, route }">
<Transition appear mode="out-in" name="slide-right">
<KeepAlive :include="['Login']">
<component
:is="Component"
:key="route.fullPath"
class="side-content mt-6 w-full sm:mx-auto md:max-w-md"
class="auth-layout__content"
/>
</KeepAlive>
</Transition>
</RouterView>
<div class="absolute bottom-3 flex text-center text-xs">
<div class="auth-layout__footer">
<span style="color: #71717a">Copyright © 2024</span>
<a href="javascript:void(0)" class="ml-2" style="color: #2080f0">MarchGlow</a>
<a href="javascript:void(0)" class="auth-layout__footer-link" style="color: #2080f0">MarchGlow</a>
</div>
</div>
</div>
@@ -31,7 +29,28 @@ const themeVars = useThemeVars()
</script>
<style scoped>
.login-background {
.auth-layout {
display: flex;
min-height: 100lvh;
flex: 1;
overflow-x: hidden;
user-select: none;
}
.auth-layout__center {
position: relative;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
}
.auth-layout__bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(
154deg,
#07070915 30%,
@@ -40,4 +59,67 @@ const themeVars = useThemeVars()
);
filter: blur(100px);
}
.auth-layout__card {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: #fff;
border-radius: 24px;
padding: 40px 24px 40px 24px;
width: 100%;
}
/* 平板端宽度 */
@media (min-width: 768px) {
.auth-layout__card {
width: 66.666%;
}
}
/* 桌面端宽度 */
@media (min-width: 1024px) {
.auth-layout__card {
width: 50%;
}
}
/* 大屏端宽度 */
@media (min-width: 1280px) {
.auth-layout__card {
width: 36%;
}
}
.auth-layout__content {
margin-top: 24px;
width: 100%;
}
@media (min-width: 640px) {
.auth-layout__content {
margin-left: auto;
margin-right: auto;
}
}
@media (min-width: 768px) {
.auth-layout__content {
max-width: 448px;
}
}
.auth-layout__footer {
position: absolute;
bottom: 12px;
display: flex;
text-align: center;
font-size: 12px;
}
.auth-layout__footer-link {
margin-left: 8px;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex-col-center">
<div class="w-full">
<h2 class="text-3xl/9 mb-3 font-bold lg:text-4xl">欢迎回来 👋🏻</h2>
<div class="login-wrapper">
<div class="login-wrapper__header">
<h2 class="login-wrapper__title">欢迎回来 👋🏻</h2>
<p>
<span style="color: #71717a">登录账号以进入对战</span>
</p>
@@ -11,7 +11,7 @@
:model="loginModel"
:rules="rules"
:show-label="false"
class="w-full mt-10"
class="login-wrapper__form"
>
<n-form-item path="username">
<n-input v-model:value="loginModel.username" placeholder="请输入账号" :maxlength="20" />
@@ -26,7 +26,7 @@
/>
</n-form-item>
<n-form-item>
<div class="flex flex-1 items-center justify-between">
<div class="login-wrapper__actions">
<n-checkbox v-model:checked="rememberAccount">记住账号</n-checkbox>
<a href="javascript:void(0)" style="color: #2080f0">忘记密码</a>
</div>
@@ -37,13 +37,13 @@
</n-button>
</n-form-item>
<n-form-item>
<div class="flex-center flex-1 gap-4">
<n-button class="flex-1" @click="router.push('/auth/phone-login')"> 手机登录 </n-button>
<n-button class="flex-1" @click="router.push('/auth/qrcode-login')"> 扫码登录 </n-button>
<div class="login-wrapper__quick-btns">
<n-button class="login-wrapper__quick-btn" @click="router.push('/auth/phone-login')"> 手机登录 </n-button>
<n-button class="login-wrapper__quick-btn" @click="router.push('/auth/qrcode-login')"> 扫码登录 </n-button>
</div>
</n-form-item>
<n-form-item>
<div class="flex-center flex-1">
<div class="login-wrapper__register-link">
<span>没有账号</span>
<router-link to="/auth/register" style="color: #2080f0">创建账号</router-link>
</div>
@@ -177,4 +177,59 @@ const userLoginFun = () => {
}
</script>
<style scoped></style>
<style scoped>
.login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.login-wrapper__header {
width: 100%;
}
.login-wrapper__title {
font-size: 30px;
line-height: 36px;
margin-bottom: 12px;
font-weight: bold;
}
@media (min-width: 1024px) {
.login-wrapper__title {
font-size: 36px;
}
}
.login-wrapper__form {
width: 100%;
margin-top: 40px;
}
.login-wrapper__actions {
display: flex;
flex: 1;
align-items: center;
justify-content: space-between;
}
.login-wrapper__quick-btns {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
gap: 16px;
}
.login-wrapper__quick-btn {
flex: 1;
}
.login-wrapper__register-link {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex-col-center">
<div class="w-full">
<h2 class="text-3xl/9 mb-3 font-bold lg:text-4xl">欢迎回来 📲</h2>
<div class="phone-login-wrapper">
<div class="phone-login-wrapper__header">
<h2 class="phone-login-wrapper__title">欢迎回来 📲</h2>
<p>
<span style="color: #71717a">请输入手机号码登录账号以进入对战</span>
</p>
@@ -11,13 +11,13 @@
:model="loginModel"
:rules="rules"
:show-label="false"
class="w-full mt-10"
class="phone-login-wrapper__form"
>
<n-form-item path="phoneNumber">
<n-input v-model:value="loginModel.phoneNumber" placeholder="手机号码" :maxlength="20" />
</n-form-item>
<n-form-item path="code">
<div class="flex flex-1 gap-4">
<div class="phone-login-wrapper__code-row">
<n-input-otp
block
v-model:value="loginModel.code"
@@ -33,8 +33,8 @@
</n-button>
</n-form-item>
<n-form-item>
<div class="flex-center flex-1 gap-4">
<n-button class="flex-1" @click="router.push('/auth/login')"> 返回 </n-button>
<div class="phone-login-wrapper__back-row">
<n-button class="phone-login-wrapper__back-btn" @click="router.push('/auth/login')"> 返回 </n-button>
</div>
</n-form-item>
</n-form>
@@ -120,4 +120,51 @@ const phoneLoginFun = () => {
}
</script>
<style scoped></style>
<style scoped>
.phone-login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.phone-login-wrapper__header {
width: 100%;
}
.phone-login-wrapper__title {
font-size: 30px;
line-height: 36px;
margin-bottom: 12px;
font-weight: bold;
}
@media (min-width: 1024px) {
.phone-login-wrapper__title {
font-size: 36px;
}
}
.phone-login-wrapper__form {
width: 100%;
margin-top: 40px;
}
.phone-login-wrapper__code-row {
display: flex;
flex: 1;
gap: 16px;
}
.phone-login-wrapper__back-row {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
gap: 16px;
}
.phone-login-wrapper__back-btn {
flex: 1;
}
</style>

View File

@@ -1,12 +1,12 @@
<template>
<div class="flex-col-center">
<div class="w-full">
<h2 class="text-3xl/9 mb-3 font-bold lg:text-4xl">欢迎回来 📱</h2>
<div class="qrcode-login-wrapper">
<div class="qrcode-login-wrapper__header">
<h2 class="qrcode-login-wrapper__title">欢迎回来 📱</h2>
<p>
<span style="color: #71717a">请用手机扫描二维码登录</span>
</p>
</div>
<n-form :show-label="false" class="w-full mt-10">
<n-form :show-label="false" class="qrcode-login-wrapper__form">
<n-form-item>
<n-space vertical style="align-items: center; flex: 1">
<n-qr-code v-model:value="qrcode" :size="180" />
@@ -14,8 +14,8 @@
</n-space>
</n-form-item>
<n-form-item>
<div class="flex-center flex-1 gap-4">
<n-button class="flex-1" @click="router.push('/auth/login')"> 返回 </n-button>
<div class="qrcode-login-wrapper__back-row">
<n-button class="qrcode-login-wrapper__back-btn" @click="router.push('/auth/login')"> 返回 </n-button>
</div>
</n-form-item>
</n-form>
@@ -32,4 +32,45 @@ const accountStore = useAccountStore()
const qrcode = ref('')
</script>
<style scoped></style>
<style scoped>
.qrcode-login-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.qrcode-login-wrapper__header {
width: 100%;
}
.qrcode-login-wrapper__title {
font-size: 30px;
line-height: 36px;
margin-bottom: 12px;
font-weight: bold;
}
@media (min-width: 1024px) {
.qrcode-login-wrapper__title {
font-size: 36px;
}
}
.qrcode-login-wrapper__form {
width: 100%;
margin-top: 40px;
}
.qrcode-login-wrapper__back-row {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
gap: 16px;
}
.qrcode-login-wrapper__back-btn {
flex: 1;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<div class="flex-col-center">
<div class="w-full">
<h2 class="text-3xl/9 mb-3 font-bold lg:text-4xl">创建一个账号 🚀</h2>
<div class="register-wrapper">
<div class="register-wrapper__header">
<h2 class="register-wrapper__title">创建一个账号 🚀</h2>
<p>
<span style="color: #71717a">创建账号进入对战</span>
</p>
@@ -11,13 +11,13 @@
:model="registerModel"
:rules="rules"
:show-label="false"
class="w-full mt-10"
class="register-wrapper__form"
>
<n-form-item path="username">
<n-input v-model:value="registerModel.username" placeholder="请输入账号" :maxlength="20" />
</n-form-item>
<n-form-item path="password">
<div class="flex flex-col flex-1">
<div class="register-wrapper__password-group">
<n-input
v-model:value="registerModel.password"
type="password"
@@ -25,39 +25,19 @@
placeholder="密码"
:maxlength="20"
/>
<div class="flex flex-1 gap-1 mt-2">
<div class="flex-1 h-2 rounded-xl relative bg-gray-200 overflow-hidden">
<div class="register-wrapper__strength-bars">
<div
v-for="level in 5"
:key="level"
class="register-wrapper__strength-bar-track"
>
<div
:class="securityLevel > 0 ? 'w-full' : 'w-0'"
class="absolute left-0 top-0 h-full bg-red-500 transition-all duration-500"
></div>
</div>
<div class="flex-1 h-2 rounded-xl relative bg-gray-200 overflow-hidden">
<div
:class="securityLevel > 1 ? 'w-full' : 'w-0'"
class="absolute left-0 top-0 h-full bg-red-500 transition-all duration-500"
></div>
</div>
<div class="flex-1 h-2 rounded-xl relative bg-gray-200 overflow-hidden">
<div
:class="securityLevel > 2 ? 'w-full' : 'w-0'"
class="absolute left-0 top-0 h-full bg-red-500 transition-all duration-500"
></div>
</div>
<div class="flex-1 h-2 rounded-xl relative bg-gray-200 overflow-hidden">
<div
:class="securityLevel > 3 ? 'w-full' : 'w-0'"
class="absolute left-0 top-0 h-full bg-red-500 transition-all duration-500"
></div>
</div>
<div class="flex-1 h-2 rounded-xl relative bg-gray-200 overflow-hidden">
<div
:class="securityLevel > 4 ? 'w-full' : 'w-0'"
class="absolute left-0 top-0 h-full bg-red-500 transition-all duration-500"
class="register-wrapper__strength-bar-fill"
:style="{ width: securityLevel >= level ? '100%' : '0' }"
></div>
</div>
</div>
<p class="text-xs mt-2" style="color: #71717a">
<p class="register-wrapper__password-hint" style="color: #71717a">
使用 8 个或更多字符混合大小写字母数字
</p>
</div>
@@ -72,7 +52,7 @@
/>
</n-form-item>
<n-form-item path="agreement">
<div class="flex flex-1">
<div class="register-wrapper__agreement">
<n-checkbox v-model:checked="registerModel.agreement">我同意</n-checkbox>
<a href="javascript:void(0)" style="color: #2080f0">隐私政策 & 条款</a>
</div>
@@ -83,7 +63,7 @@
</n-button>
</n-form-item>
<n-form-item>
<div class="flex-center flex-1">
<div class="register-wrapper__login-link">
<span>已经有账号了</span>
<router-link to="/auth/login" style="color: #2080f0">去登录</router-link>
</div>
@@ -247,4 +227,81 @@ const userRegisterFun = () => {
}
</script>
<style scoped></style>
<style scoped>
.register-wrapper {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.register-wrapper__header {
width: 100%;
}
.register-wrapper__title {
font-size: 30px;
line-height: 36px;
margin-bottom: 12px;
font-weight: bold;
}
@media (min-width: 1024px) {
.register-wrapper__title {
font-size: 36px;
}
}
.register-wrapper__form {
width: 100%;
margin-top: 40px;
}
.register-wrapper__password-group {
display: flex;
flex-direction: column;
flex: 1;
}
.register-wrapper__strength-bars {
display: flex;
flex: 1;
gap: 4px;
margin-top: 8px;
}
.register-wrapper__strength-bar-track {
flex: 1;
height: 8px;
border-radius: 12px;
position: relative;
background-color: #e5e7eb;
overflow: hidden;
}
.register-wrapper__strength-bar-fill {
position: absolute;
left: 0;
top: 0;
height: 100%;
background-color: #ef4444;
transition: all 500ms;
}
.register-wrapper__password-hint {
font-size: 12px;
margin-top: 8px;
}
.register-wrapper__agreement {
display: flex;
flex: 1;
}
.register-wrapper__login-link {
display: flex;
align-items: center;
justify-content: center;
flex: 1;
}
</style>

View File

@@ -4,7 +4,6 @@ import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import tailwindcss from '@tailwindcss/vite'
import AutoImport from 'unplugin-auto-import/vite'
import { NaiveUiResolver } from 'unplugin-vue-components/resolvers'
@@ -16,7 +15,6 @@ export default defineConfig({
vue(),
vueJsx(),
vueDevTools(),
tailwindcss(),
AutoImport({
imports: [{ 'native-ui': ['useDialog', 'useMessage', 'useNotification', 'useLoadingBar'] }]
}),