-
2.env
-
2.env.development
-
5.gitignore
-
2.husky/common.sh
-
11.markdownlint.json
-
4.prettierrc.js
-
51.vscode/settings.json
-
22.vscode/vue3.0.code-snippets
-
20.vscode/vue3.2.setup-snippets
-
14README.en-US.md
-
10README.md
-
37index.html
-
3mock/asyncRoutes.ts
-
109package.json
-
6529pnpm-lock.yaml
-
BINpublic/favicon.ico
-
17public/serverConfig.json
-
8src/App.vue
-
2src/api/routes.ts
-
BINsrc/assets/401.gif
-
BINsrc/assets/bg.png
-
BINsrc/assets/car.png
-
26src/assets/iconfont/iconfont.css
-
44src/assets/iconfont/iconfont.js
-
38src/assets/iconfont/iconfont.json
-
BINsrc/assets/iconfont/iconfont.ttf
-
BINsrc/assets/iconfont/iconfont.woff
-
BINsrc/assets/iconfont/iconfont.woff2
-
BINsrc/assets/login.png
-
1src/assets/login/avatar.svg
-
BINsrc/assets/login/bg.png
-
1src/assets/login/illustration0.svg
-
1src/assets/login/illustration1.svg
-
1src/assets/login/illustration2.svg
-
1src/assets/login/illustration3.svg
-
1src/assets/login/illustration4.svg
-
1src/assets/login/illustration5.svg
-
1src/assets/login/illustration6.svg
-
1src/assets/svg/back_top.svg
-
195src/components/ReInfo/index.vue
-
138src/layout/components/appMain.vue
-
26src/layout/components/navbar.vue
-
25src/layout/components/panel/index.vue
-
408src/layout/components/setting/index.vue
-
6src/layout/components/sidebar/hamBurger.vue
-
25src/layout/components/sidebar/horizontal.vue
-
25src/layout/components/sidebar/logo.vue
-
97src/layout/components/sidebar/sidebarItem.vue
-
2src/layout/components/sidebar/vertical.vue
-
18src/layout/components/tag/index.vue
-
157src/layout/index.vue
-
12src/layout/theme/auroraGreen-vars.scss
-
24src/layout/theme/default-vars.scss
-
12src/layout/theme/dusk-vars.scss
-
11src/layout/theme/light-vars.scss
-
12src/layout/theme/mingQing-vars.scss
-
12src/layout/theme/pink-vars.scss
-
12src/layout/theme/saucePurple-vars.scss
-
12src/layout/theme/volcano-vars.scss
-
12src/layout/theme/yellow-vars.scss
-
7src/layout/types.ts
-
4src/main.ts
-
44src/plugins/element-plus/index.ts
-
75src/plugins/i18n/config.ts
-
1src/plugins/i18n/index.ts
-
119src/plugins/vxe-table/index.ts
-
11src/router/index.ts
-
2src/router/modules/error.ts
-
25src/router/modules/externalLink.ts
-
2src/router/modules/home.ts
-
12src/router/modules/remaining.ts
-
5src/store/modules/app.ts
-
4src/style/element-plus.scss
-
14src/style/index.scss
-
227src/style/login.css
-
320src/style/sidebar.scss
-
28src/utils/http/core.ts
-
13src/utils/storage/responsive.ts
-
184src/views/login.vue
-
2src/views/permission/button/index.vue
-
4src/views/permission/page/index.vue
-
17src/views/register.vue
-
4types/global.d.ts
-
76vite.config.ts
-
4583yarn.lock
@ -0,0 +1,11 @@ |
|||||
|
{ |
||||
|
"default": true, |
||||
|
"MD003": false, |
||||
|
"MD033": false, |
||||
|
"MD013": false, |
||||
|
"MD001": false, |
||||
|
"MD025": false, |
||||
|
"MD024": false, |
||||
|
"MD007": { "indent": 4 }, |
||||
|
"no-hard-tabs": false |
||||
|
} |
@ -0,0 +1,51 @@ |
|||||
|
{ |
||||
|
// You should install these plugins: |
||||
|
// ESLint |
||||
|
// Prettier - Code formatter |
||||
|
// stylelint |
||||
|
// vscode-icons |
||||
|
// TypeScript Vue Plugin (Volar) |
||||
|
// Vue Language Features (Volar) |
||||
|
"terminal.integrated.rendererType": "dom", |
||||
|
"editor.formatOnType": true, |
||||
|
"editor.formatOnSave": true, |
||||
|
"javascript.updateImportsOnFileMove.enabled": "always", |
||||
|
"[vue]": { |
||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||
|
}, |
||||
|
"[javascript]": { |
||||
|
"editor.defaultFormatter": "vscode.typescript-language-features" |
||||
|
}, |
||||
|
"editor.tabSize": 2, |
||||
|
"editor.formatOnPaste": true, |
||||
|
"files.autoSave": "afterDelay", |
||||
|
"git.confirmSync": false, |
||||
|
"workbench.startupEditor": "newUntitledFile", |
||||
|
"editor.suggestSelection": "first", |
||||
|
"editor.acceptSuggestionOnCommitCharacter": false, |
||||
|
"css.lint.propertyIgnoredDueToDisplay": "ignore", |
||||
|
// Prevent inline styles from being automatically formatted to all lowercase |
||||
|
"editor.quickSuggestions": { |
||||
|
"other": true, |
||||
|
"comments": true, |
||||
|
"strings": true |
||||
|
}, |
||||
|
// Automatically fix some syntax errors of ts |
||||
|
"tslint.autoFixOnSave": true, |
||||
|
"files.associations": { |
||||
|
// Specifies the location of snippets in the suggestion widget |
||||
|
"editor.snippetSuggestions": "top" |
||||
|
}, |
||||
|
"[css]": { |
||||
|
"editor.defaultFormatter": "esbenp.prettier-vscode" |
||||
|
}, |
||||
|
"cSpell.userWords": ["sourcemap", "vite"], |
||||
|
"editor.codeActionsOnSave": { |
||||
|
"source.fixAll.eslint": true |
||||
|
}, |
||||
|
"volar.tsPlugin": true, |
||||
|
"typescript.tsdk": "node_modules/typescript/lib", |
||||
|
"i18n-ally.localesPaths": [ |
||||
|
"src/plugins/i18n" |
||||
|
] |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
{ |
||||
|
"Vue3.0快速生成模板": { |
||||
|
"prefix": "Vue3.0", |
||||
|
"body": [ |
||||
|
"<template>", |
||||
|
"\t<div>\n", |
||||
|
"\t</div>", |
||||
|
"</template>\n", |
||||
|
"<script lang='ts'>", |
||||
|
"export default {", |
||||
|
"\tsetup(){", |
||||
|
"\t\treturn{\n\n\t\t}", |
||||
|
"\t},", |
||||
|
"}", |
||||
|
"</script>\n", |
||||
|
"<style scoped>\n", |
||||
|
"</style>", |
||||
|
"$2" |
||||
|
], |
||||
|
"description": "Vue3.0" |
||||
|
} |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
{ |
||||
|
"Vue3.2快速生成模板": { |
||||
|
"prefix": "Vue3.2", |
||||
|
"body": [ |
||||
|
"<!-- $1 -->", |
||||
|
"<script setup lang='ts'>", |
||||
|
"\t$2", |
||||
|
"</script>\n", |
||||
|
"<template>", |
||||
|
"\t<div>", |
||||
|
"\t\t$3", |
||||
|
"\t</div>", |
||||
|
"</template>\n", |
||||
|
"<style scoped>", |
||||
|
"\t$4", |
||||
|
"</style>" |
||||
|
], |
||||
|
"description": "Vue3.2" |
||||
|
} |
||||
|
} |
@ -1 +1,13 @@ |
|||||
<h1>vue-pure-admin精简版</h1> |
|
||||
|
<h1>vue-pure-admin Lite Edition</h1> |
||||
|
|
||||
|
## introduce |
||||
|
|
||||
|
The lite version is based on the shelf extracted from https://github.com/xiaoxian521/vue-pure-admin, which contains the main functions and is more suitable for actual project development |
||||
|
|
||||
|
## Supporting video tutorial |
||||
|
|
||||
|
bilibili: https://www.bilibili.com/video/BV1534y1S7HV/ |
||||
|
|
||||
|
## ⚠️ Note |
||||
|
|
||||
|
The lite version does not accept any issues and prs. If you have any questions, please go to the full version https://github.com/xiaoxian521/vue-pure-admin/issues/new/choose to mention it, thank you! ! ! |
@ -1,11 +1,13 @@ |
|||||
<h1>vue-pure-admin精简版</h1> |
<h1>vue-pure-admin精简版</h1> |
||||
|
|
||||
|
## 介绍 |
||||
|
|
||||
|
精简版是基于 https://github.com/xiaoxian521/vue-pure-admin 提炼出的架子,包含主体功能,更适合实际项目开发 |
||||
|
|
||||
## 配套视频教程 |
## 配套视频教程 |
||||
|
|
||||
bilibili:https://www.bilibili.com/video/BV1534y1S7HV/ |
bilibili:https://www.bilibili.com/video/BV1534y1S7HV/ |
||||
|
|
||||
## 交流群 |
|
||||
|
|
||||
[微信交流群,点击扫码进群](https://juejin.cn/post/6948419379566477342/) |
|
||||
|
## ⚠️ 注意 |
||||
|
|
||||
本人微信:18237613535,拉你进群 |
|
||||
|
精简版不接受任何 issues 和 pr,如果有问题请到完整版 https://github.com/xiaoxian521/vue-pure-admin/issues/new/choose 去提,谢谢!!! |
6529
pnpm-lock.yaml
File diff suppressed because it is too large
View File
After Width: 32 | Height: 32 | Size: 1.2 KiB |
@ -1,9 +1,22 @@ |
|||||
{ |
{ |
||||
"Version": "2.1.0", |
|
||||
|
"Version": "2.6.0", |
||||
"Title": "PureAdmin", |
"Title": "PureAdmin", |
||||
"FixedHeader": true, |
"FixedHeader": true, |
||||
"HiddenSideBar": false, |
"HiddenSideBar": false, |
||||
"KeepAlive": true, |
"KeepAlive": true, |
||||
"Locale": "zh", |
"Locale": "zh", |
||||
"Layout": "vertical-dark" |
|
||||
|
"Layout": "vertical", |
||||
|
"Theme": "default", |
||||
|
"Grey": false, |
||||
|
"Weak": false, |
||||
|
"HideTabs": false, |
||||
|
"MapConfigure": { |
||||
|
"amapKey": "97b3248d1553172e81f168cf94ea667e", |
||||
|
"baiduKey": "wTHbkkEweiFqZLKunMIjcrb2RcqNXkhc", |
||||
|
"options": { |
||||
|
"resizeEnable": true, |
||||
|
"center": [113.6401, 34.72468], |
||||
|
"zoom": 12 |
||||
|
} |
||||
|
} |
||||
} |
} |
@ -1,4 +1,4 @@ |
|||||
import { http } from "/@/utils/http"; |
|
||||
|
import { http } from "../utils/http"; |
||||
|
|
||||
export const getAsyncRoutes = (data?: object) => { |
export const getAsyncRoutes = (data?: object) => { |
||||
return http.request("get", "/getAsyncRoutes", data); |
return http.request("get", "/getAsyncRoutes", data); |
||||
|
Before Width: 313 | Height: 428 | Size: 160 KiB After Width: 313 | Height: 428 | Size: 680 KiB |
Before Width: 1920 | Height: 1080 | Size: 1.1 MiB |
After Width: 36 | Height: 20 | Size: 1.4 KiB |
44
src/assets/iconfont/iconfont.js
File diff suppressed because it is too large
View File
Before Width: 607 | Height: 716 | Size: 9.9 KiB |
@ -0,0 +1 @@ |
|||||
|
<svg t="1636193306629" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1847" width="32" height="32"><path d="M410.558481 0.10861C410.558481 211.083075 109.682285 361.860579 109.682285 633.656511c0 174.943176 134.703259 316.787527 300.876196 316.787527s300.876197-141.817198 300.876197-316.787527C711.407525 361.751969 410.558481 210.974465 410.558481 0.10861z" fill="#386BF3" p-id="1848"></path><path d="M613.468671 73.664572c0 211.055922-300.876197 361.914883-300.876196 633.547901 0 174.943176 134.703259 316.787527 300.876196 316.787527s300.876197-141.817198 300.876197-316.787527c-0.054305-271.633018-300.876197-422.491979-300.876197-633.547901z" fill="#C3D2FB" p-id="1849"></path><path d="M312.592475 707.212473c0-183.713414 137.635722-312.171612 226.72288-441.390078 81.701694 106.111739 172.119322 218.740063 172.119323 367.725506a309.755045 309.755045 0 0 1-291.074166 316.516003 323.114046 323.114046 0 0 1-107.768037-242.851431z" fill="#303F5B" p-id="1850"></path></svg> |
After Width: 1920 | Height: 1080 | Size: 17 KiB |
1
src/assets/login/illustration0.svg
File diff suppressed because it is too large
View File
1
src/assets/login/illustration1.svg
File diff suppressed because it is too large
View File
@ -0,0 +1 @@ |
|||||
|
<svg xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" width="500" height="380" viewBox="0 0 896 529.1129" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M832.06729,623.22778s-26.37759,9.89441-38.806,32.94348S787.06,706.69574,787.06,706.69574s26.37759-9.89447,38.806-32.94348S832.06729,623.22778,832.06729,623.22778Z" transform="translate(-158 -185.8871)" fill="#3f3d56"/><path d="M867.5,657.59637s-8.64182,26.814-31.0802,40.31373-50.17651,8.57293-50.17651,8.57293,8.64175-26.81408,31.08017-40.31378S867.5,657.59637,867.5,657.59637Z" transform="translate(-158 -185.8871)" fill="#5392f0"/><rect y="527.1129" width="896" height="2" fill="#2f2e41"/><path d="M519.87238,620.97461a95.44448,95.44448,0,0,1-35.748-14.44629L485.306,604.915a93.36283,93.36283,0,0,0,34.999,14.10547c18.93164,3.40137,47.26075,1.73144,74.707-25.52735,53.41358-53.04785,104.39307-58.39062,104.90186-58.43847l.18652,1.99219c-.50146.04687-50.76806,5.31738-103.67822,57.86621-21.61328,21.46386-43.792,27.40234-61.71777,27.40234A83.49962,83.49962,0,0,1,519.87238,620.97461Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><circle cx="515.15271" cy="381.1129" r="12" fill="#2f2e41"/><circle cx="430.15271" cy="437.1129" r="12" fill="#2f2e41"/><path d="M841.5,714s-17.46191-5.41315-52.26129-10.84192L790,692.5c6-60-34-150-34-150a401.561,401.561,0,0,1,21.4693,139.0246C772.13214,672.2124,761.82056,662.16638,742,656c0,0,25.77765,22.106,33.15918,45.10175a997.84042,997.84042,0,0,0-102.02258-8.21589L682,672.5l-17,17s-7-51-22-53l11,50s-13-10-16-9l7.39746,14.79486c-49.819-.51654-109.08453,1.7356-177.76581,8.95227L476,682l-17,17s-7-51-22-53l11,50s-13-10-16-9l8.64288,17.28583Q406.9763,708.2897,370.5,714Z" transform="translate(-158 -185.8871)" fill="#3f3d56"/><path d="M565.64813,230.37817c-10.89964,11.74783,17.59745,40.25959,17.59745,40.25959s-57.70662,9.73051-53.12783,9.14083,2.20622-49.13151,2.20622-49.13151S576.54777,218.63035,565.64813,230.37817Z" transform="translate(-158 -185.8871)" fill="#a0616a"/><path d="M605.81236,356.10945l-50.139,25.6141-27.22969,15.6059s-32.09862,40.43116-38.08709,64.39234,25.92963,68.247,29.54371,72.82286a54.36088,54.36088,0,0,1,4.98908,7.42355c1.24727,1.85589,12.02944-.541,23.80342-3.06554S547.13,518.93875,547.13,518.93875s-15.02732-38.39505-16.14686-39.25912c-1.04554-.807-4.60093-7.44631-2.04309-10.35234a25.94993,25.94993,0,0,0,5.44489-8.89825,30.09064,30.09064,0,0,1,4.18709-7.94151s45.361-36.83645,59.52776-49.37835,51.82952-4.65839,51.82952-4.65839-17.78167,68.20027-22.22979,72.80616-4.929,8.70085-2.91535,16.50759,28.28157.39078,28.28157.39078L662.766,461.6996s15.74879-34.2925,24.29946-69.67451c4.27533-17.691-3.88828-28.23462-13.12073-34.35549a41.39094,41.39094,0,0,0-30.02983-5.97766l-46.34848,8.1308,32.14706-13.84923Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><path d="M420.87777,290.19133,361.02366,271.685s-24.179-31.16689-12.78824-36.6669,25.65172,26.94419,25.65172,26.94419l41.686,2.69751Z" transform="translate(-158 -185.8871)" fill="#a0616a"/><path d="M672.49431,257.78673l53.2121-33.06768s15.49333-36.27612,3.0807-38.71059-17.98787,32.56435-17.98787,32.56435l-39.64232,13.17143Z" transform="translate(-158 -185.8871)" fill="#a0616a"/><path d="M682.45318,220.40023l1.01427,39.19147-89.68779,16.025c13.19231,28.22441,9.84118,60.34675,43.04725,74.4259L524.9027,404.78717c4.9871-43.03806-15.81748-75.456-35.263-115.75876-23.68547-8.58589-51.19594-2.29078-80.33649,10.34619l-5.237-40.66416,123.87841-8.896,20.34848,7.77932,21.81842-9.17677C602.17891,238.88953,648.22076,220.77584,682.45318,220.40023Z" transform="translate(-158 -185.8871)" fill="#5392f0"/><path d="M626.64006,486.51727c-2.72,2.36681-5.25213,21.84984-5.34982,28.92023s9.21178,8.89624,14.29855,9.2494,4.47816,3.45631,7.83678,6.04854,14.39625,2.179,28.89019-2.71238-9.75274-20.92568-11.86409-21.662-11-22.78156-11-22.78156S629.36,484.15046,626.64006,486.51727Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><path d="M547.368,531.00717c3.23089,1.60043,10.61681,19.80614,12.50274,26.62107s-6.65716,10.93994-11.48848,12.5704-3.45631,4.47816-6.04855,7.83678-13.3744,5.75546-28.63472,4.696,4.13258-22.71391,5.98847-23.96118,4.86893-24.82526,4.86893-24.82526S544.13715,529.40674,547.368,531.00717Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/><circle cx="389.47074" cy="35.42904" r="23.99585" fill="#a0616a"/><path d="M519.73448,218.90923a22.82668,22.82668,0,0,1-.83378-18.59281c2.35891-5.8153,7.59174-11.65569,18.87309-13.4,24.61387-3.80572,37.71267,13.43543,37.02452,19.07449s-3.99294,19.27051-3.99294,19.27051,1.47587-12.90619-4.85883-13.362-30.90178-2.37835-37.12217,4.145a14.23268,14.23268,0,0,0-3.71042,13.82977Z" transform="translate(-158 -185.8871)" fill="#2f2e41"/></svg> |
1
src/assets/login/illustration3.svg
File diff suppressed because it is too large
View File
1
src/assets/login/illustration4.svg
File diff suppressed because it is too large
View File
1
src/assets/login/illustration5.svg
File diff suppressed because it is too large
View File
1
src/assets/login/illustration6.svg
File diff suppressed because it is too large
View File
@ -0,0 +1 @@ |
|||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24"><path fill="none" d="M0 0h24v24H0z"/><path d="M2.88 18.054a35.897 35.897 0 0 1 8.531-16.32.8.8 0 0 1 1.178 0c.166.18.304.332.413.455a35.897 35.897 0 0 1 8.118 15.865c-2.141.451-4.34.747-6.584.874l-2.089 4.178a.5.5 0 0 1-.894 0l-2.089-4.178a44.019 44.019 0 0 1-6.584-.874zm6.698-1.123l1.157.066L12 19.527l1.265-2.53 1.157-.066a42.137 42.137 0 0 0 4.227-.454A33.913 33.913 0 0 0 12 4.09a33.913 33.913 0 0 0-6.649 12.387c1.395.222 2.805.374 4.227.454zM12 15a3 3 0 1 1 0-6 3 3 0 0 1 0 6zm0-2a1 1 0 1 0 0-2 1 1 0 0 0 0 2z"/></svg> |
@ -1,195 +0,0 @@ |
|||||
<script setup lang="ts"> |
|
||||
import { ref, PropType, getCurrentInstance, watch, nextTick, toRef } from "vue"; |
|
||||
import { useRouter, useRoute } from "vue-router"; |
|
||||
import { initRouter } from "/@/router"; |
|
||||
import { storageSession } from "/@/utils/storage"; |
|
||||
|
|
||||
export interface ContextProps { |
|
||||
userName: string; |
|
||||
passWord: string; |
|
||||
verify: number | null; |
|
||||
svg: any; |
|
||||
telephone?: number; |
|
||||
dynamicText?: string; |
|
||||
} |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
ruleForm: { |
|
||||
type: Object as PropType<ContextProps> |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
const emit = defineEmits<{ |
|
||||
(e: "onBehavior", evt: Object): void; |
|
||||
(e: "refreshVerify"): void; |
|
||||
}>(); |
|
||||
|
|
||||
const instance = getCurrentInstance(); |
|
||||
|
|
||||
const model = toRef(props, "ruleForm"); |
|
||||
let tips = ref<string>("注册"); |
|
||||
let tipsFalse = ref<string>("登录"); |
|
||||
|
|
||||
const route = useRoute(); |
|
||||
const router = useRouter(); |
|
||||
|
|
||||
watch( |
|
||||
route, |
|
||||
async ({ path }): Promise<void> => { |
|
||||
await nextTick(); |
|
||||
path.includes("register") |
|
||||
? (tips.value = "登录") && (tipsFalse.value = "注册") |
|
||||
: (tips.value = "注册") && (tipsFalse.value = "登录"); |
|
||||
}, |
|
||||
{ immediate: true } |
|
||||
); |
|
||||
|
|
||||
const rules = ref<any>({ |
|
||||
userName: [{ required: true, message: "请输入用户名", trigger: "blur" }], |
|
||||
passWord: [ |
|
||||
{ required: true, message: "请输入密码", trigger: "blur" }, |
|
||||
{ min: 6, message: "密码长度必须不小于6位", trigger: "blur" } |
|
||||
], |
|
||||
verify: [ |
|
||||
{ required: true, message: "请输入验证码", trigger: "blur" }, |
|
||||
{ type: "number", message: "验证码必须是数字类型", trigger: "blur" } |
|
||||
] |
|
||||
}); |
|
||||
|
|
||||
// 点击登录或注册 |
|
||||
const onBehavior = (evt: Object): void => { |
|
||||
// @ts-expect-error |
|
||||
instance.refs.ruleForm.validate((valid: boolean) => { |
|
||||
if (valid) { |
|
||||
emit("onBehavior", evt); |
|
||||
} else { |
|
||||
return false; |
|
||||
} |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
// 刷新验证码 |
|
||||
const refreshVerify = (): void => { |
|
||||
emit("refreshVerify"); |
|
||||
}; |
|
||||
|
|
||||
// 表单重置 |
|
||||
const resetForm = (): void => { |
|
||||
// @ts-expect-error |
|
||||
instance.refs.ruleForm.resetFields(); |
|
||||
}; |
|
||||
|
|
||||
// 登录、注册页面切换 |
|
||||
const changPage = (): void => { |
|
||||
tips.value === "注册" ? router.push("/register") : router.push("/login"); |
|
||||
}; |
|
||||
|
|
||||
const noSecret = (): void => { |
|
||||
storageSession.setItem("info", { |
|
||||
username: "admin", |
|
||||
accessToken: "eyJhbGciOiJIUzUxMiJ9.test" |
|
||||
}); |
|
||||
initRouter("admin").then(() => {}); |
|
||||
router.push("/"); |
|
||||
}; |
|
||||
</script> |
|
||||
|
|
||||
<template> |
|
||||
<div class="info"> |
|
||||
<el-form :model="model" :rules="rules" ref="ruleForm" class="rule-form"> |
|
||||
<el-form-item prop="userName"> |
|
||||
<el-input |
|
||||
clearable |
|
||||
v-model="model.userName" |
|
||||
placeholder="请输入用户名" |
|
||||
prefix-icon="el-icon-user" |
|
||||
></el-input> |
|
||||
</el-form-item> |
|
||||
<el-form-item prop="passWord"> |
|
||||
<el-input |
|
||||
clearable |
|
||||
type="password" |
|
||||
show-password |
|
||||
v-model="model.passWord" |
|
||||
placeholder="请输入密码" |
|
||||
prefix-icon="el-icon-lock" |
|
||||
></el-input> |
|
||||
</el-form-item> |
|
||||
<el-form-item prop="verify"> |
|
||||
<el-input |
|
||||
maxlength="2" |
|
||||
onkeyup="this.value=this.value.replace(/[^\d.]/g,'');" |
|
||||
v-model.number="model.verify" |
|
||||
placeholder="请输入验证码" |
|
||||
></el-input> |
|
||||
<span |
|
||||
class="verify" |
|
||||
title="刷新" |
|
||||
v-html="model.svg" |
|
||||
@click.prevent="refreshVerify" |
|
||||
></span> |
|
||||
</el-form-item> |
|
||||
<el-form-item> |
|
||||
<el-button type="primary" @click.prevent="onBehavior">{{ |
|
||||
tipsFalse |
|
||||
}}</el-button> |
|
||||
<el-button @click="resetForm">重置</el-button> |
|
||||
<span class="tips" @click="changPage">{{ tips }}</span> |
|
||||
</el-form-item> |
|
||||
<span title="测试用户 直接登录" class="secret" @click="noSecret" |
|
||||
>免密登录</span |
|
||||
> |
|
||||
</el-form> |
|
||||
</div> |
|
||||
</template> |
|
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.info { |
|
||||
width: 30vw; |
|
||||
height: 48vh; |
|
||||
background: url("../../assets/login.png") no-repeat center; |
|
||||
background-size: cover; |
|
||||
position: absolute; |
|
||||
border-radius: 20px; |
|
||||
right: 100px; |
|
||||
top: 30vh; |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
align-items: center; |
|
||||
@media screen and (max-width: 750px) { |
|
||||
width: 88vw; |
|
||||
right: 25px; |
|
||||
top: 22vh; |
|
||||
} |
|
||||
|
|
||||
.rule-form { |
|
||||
width: 80%; |
|
||||
|
|
||||
.verify { |
|
||||
position: absolute; |
|
||||
margin: -10px 0 0 -120px; |
|
||||
|
|
||||
&:hover { |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.tips { |
|
||||
color: #409eff; |
|
||||
float: right; |
|
||||
|
|
||||
&:hover { |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
.secret { |
|
||||
color: #409eff; |
|
||||
|
|
||||
&:hover { |
|
||||
cursor: pointer; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
</style> |
|
@ -0,0 +1,12 @@ |
|||||
|
// 极光绿 |
||||
|
|
||||
|
$subMenuActiveText: #fff; |
||||
|
$menuBg: #0b1e15; |
||||
|
$menuHover: #60ac80; |
||||
|
$subMenuBg: #000; |
||||
|
$subMenuActiveBg: #60ac80; |
||||
|
$navTextColor: #7a80b4; |
||||
|
$menuText: #7a80b4; |
||||
|
$sidebarLogo: #112f21; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #60ac80; |
@ -0,0 +1,24 @@ |
|||||
|
/** |
||||
|
*此scss变量文件作为multipleScopeVars去编译时,会自动移除!default以达到变量提升 |
||||
|
*同时此scss变量文件作为默认主题变量文件,被其他.scss通过 @import 时,必需 !default |
||||
|
*/ |
||||
|
|
||||
|
// 暗雅(默认) |
||||
|
|
||||
|
// 菜单选中后字体样式 |
||||
|
$subMenuActiveText: #fff !default; |
||||
|
//菜单背景 |
||||
|
$menuBg: #001529 !default; |
||||
|
// 鼠标覆盖到菜单时的背景 |
||||
|
$menuHover: #4091f7 !default; |
||||
|
// 子菜单背景 |
||||
|
$subMenuBg: #0f0303 !default; |
||||
|
// 有无子集的激活菜单背景 |
||||
|
$subMenuActiveBg: #4091f7 !default; |
||||
|
$navTextColor: #fff !default; |
||||
|
$menuText: rgba(254, 254, 254, 0.65) !default; |
||||
|
// logo背景颜色 |
||||
|
$sidebarLogo: #002140 !default; |
||||
|
// 鼠标覆盖到菜单时的字体颜色 |
||||
|
$menuTitleHover: #fff !default; |
||||
|
$menuActiveBefore: #4091f7 !default; |
@ -0,0 +1,12 @@ |
|||||
|
// 薄暮 |
||||
|
|
||||
|
$subMenuActiveText: #fff; |
||||
|
$menuBg: #2a0608; |
||||
|
$menuHover: #e13c39; |
||||
|
$subMenuBg: #000; |
||||
|
$subMenuActiveBg: #e13c39; |
||||
|
$navTextColor: red; |
||||
|
$menuText: rgba(254, 254, 254, 0.651); |
||||
|
$sidebarLogo: #42090c; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #e13c39; |
@ -0,0 +1,11 @@ |
|||||
|
// 明亮 |
||||
|
$subMenuActiveText: #409eff; |
||||
|
$menuBg: #fff; |
||||
|
$menuHover: #e0ebf6; |
||||
|
$subMenuBg: #fff; |
||||
|
$subMenuActiveBg: #e0ebf6; |
||||
|
$navTextColor: #7a80b4; |
||||
|
$menuText: #7a80b4; |
||||
|
$sidebarLogo: #fff; |
||||
|
$menuTitleHover: #000; |
||||
|
$menuActiveBefore: #4091f7; |
@ -0,0 +1,12 @@ |
|||||
|
// 明青 |
||||
|
|
||||
|
$subMenuActiveText: #fff; |
||||
|
$menuBg: #032121; |
||||
|
$menuHover: #59bfc1; |
||||
|
$subMenuBg: #000; |
||||
|
$subMenuActiveBg: #59bfc1; |
||||
|
$navTextColor: #7a80b4; |
||||
|
$menuText: #7a80b4; |
||||
|
$sidebarLogo: #053434; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #59bfc1; |
@ -0,0 +1,12 @@ |
|||||
|
// 粉红 |
||||
|
|
||||
|
$subMenuActiveText: #fff; |
||||
|
$menuBg: #28081a; |
||||
|
$menuHover: #d84493; |
||||
|
$subMenuBg: #000; |
||||
|
$subMenuActiveBg: #d84493; |
||||
|
$navTextColor: #7a80b4; |
||||
|
$menuText: #7a80b4; |
||||
|
$sidebarLogo: #3f0d29; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #d84493; |
@ -0,0 +1,12 @@ |
|||||
|
// 酱紫 |
||||
|
|
||||
|
$subMenuActiveText: #fff; |
||||
|
$menuBg: #130824; |
||||
|
$menuHover: #693ac9; |
||||
|
$subMenuBg: #000; |
||||
|
$subMenuActiveBg: #693ac9; |
||||
|
$navTextColor: #7a80b4; |
||||
|
$menuText: #7a80b4; |
||||
|
$sidebarLogo: #1f0c38; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #693ac9; |
@ -0,0 +1,12 @@ |
|||||
|
// 火山 |
||||
|
|
||||
|
$subMenuActiveText: #fff; |
||||
|
$menuBg: #2b0e05; |
||||
|
$menuHover: #e85f33; |
||||
|
$subMenuBg: #0f0603; |
||||
|
$subMenuActiveBg: #e85f33; |
||||
|
$navTextColor: #fff; |
||||
|
$menuText: rgba(254, 254, 254, 0.65); |
||||
|
$sidebarLogo: #441708; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #e85f33; |
@ -0,0 +1,12 @@ |
|||||
|
// 黄色 |
||||
|
|
||||
|
$subMenuActiveText: #d25f00; |
||||
|
$menuBg: #2b2503; |
||||
|
$menuHover: #f6da4d; |
||||
|
$subMenuBg: #0f0603; |
||||
|
$subMenuActiveBg: #f6da4d; |
||||
|
$navTextColor: #fff; |
||||
|
$menuText: rgba(254, 254, 254, 0.65); |
||||
|
$sidebarLogo: #443b05; |
||||
|
$menuTitleHover: #fff; |
||||
|
$menuActiveBefore: #f6da4d; |
@ -1,119 +0,0 @@ |
|||||
import "xe-utils"; |
|
||||
import { App } from "vue"; |
|
||||
import { i18n } from "../i18n/index"; |
|
||||
import "font-awesome/css/font-awesome.css"; |
|
||||
import { |
|
||||
// 核心
|
|
||||
VXETable, |
|
||||
|
|
||||
// 表格功能
|
|
||||
Header, |
|
||||
Footer, |
|
||||
Icon, |
|
||||
Filter, |
|
||||
Edit, |
|
||||
Menu, |
|
||||
Export, |
|
||||
Keyboard, |
|
||||
Validator, |
|
||||
|
|
||||
// 可选组件
|
|
||||
Column, |
|
||||
Colgroup, |
|
||||
Grid, |
|
||||
Tooltip, |
|
||||
Toolbar, |
|
||||
Pager, |
|
||||
Form, |
|
||||
FormItem, |
|
||||
FormGather, |
|
||||
Checkbox, |
|
||||
CheckboxGroup, |
|
||||
Radio, |
|
||||
RadioGroup, |
|
||||
RadioButton, |
|
||||
Switch, |
|
||||
Input, |
|
||||
Select, |
|
||||
Optgroup, |
|
||||
Option, |
|
||||
Textarea, |
|
||||
Button, |
|
||||
Modal, |
|
||||
List, |
|
||||
Pulldown, |
|
||||
|
|
||||
// 表格
|
|
||||
Table |
|
||||
} from "vxe-table"; |
|
||||
|
|
||||
// 全局默认参数
|
|
||||
VXETable.setup({ |
|
||||
size: "medium", |
|
||||
version: 0, |
|
||||
zIndex: 1002, |
|
||||
table: { |
|
||||
// 自动监听父元素的变化去重新计算表格
|
|
||||
autoResize: true, |
|
||||
// 鼠标移到行是否要高亮显示
|
|
||||
highlightHoverRow: true |
|
||||
}, |
|
||||
input: { |
|
||||
clearable: true |
|
||||
}, |
|
||||
// 对组件内置的提示语进行国际化翻译
|
|
||||
// @ts-ignore
|
|
||||
i18n: (key, args) => i18n.global.t(key, args), |
|
||||
// 可选,对参数中的列头、校验提示..等进行自动翻译(只对支持国际化的有效)
|
|
||||
translate(key, args) { |
|
||||
// 例如,只翻译 "message." 开头的键值
|
|
||||
if (key && key.indexOf("message.") > -1) { |
|
||||
return i18n.global.t(key, args); |
|
||||
} |
|
||||
if (key && key.indexOf("el.") > -1) { |
|
||||
return i18n.global.t(key, args); |
|
||||
} |
|
||||
return key; |
|
||||
} |
|
||||
}); |
|
||||
|
|
||||
export function useTable(app: App) { |
|
||||
app |
|
||||
.use(Header) |
|
||||
.use(Footer) |
|
||||
.use(Icon) |
|
||||
.use(Filter) |
|
||||
.use(Edit) |
|
||||
.use(Menu) |
|
||||
.use(Export) |
|
||||
.use(Keyboard) |
|
||||
.use(Validator) |
|
||||
|
|
||||
// 可选组件
|
|
||||
.use(Column) |
|
||||
.use(Colgroup) |
|
||||
.use(Grid) |
|
||||
.use(Tooltip) |
|
||||
.use(Toolbar) |
|
||||
.use(Pager) |
|
||||
.use(Form) |
|
||||
.use(FormItem) |
|
||||
.use(FormGather) |
|
||||
.use(Checkbox) |
|
||||
.use(CheckboxGroup) |
|
||||
.use(Radio) |
|
||||
.use(RadioGroup) |
|
||||
.use(RadioButton) |
|
||||
.use(Switch) |
|
||||
.use(Input) |
|
||||
.use(Select) |
|
||||
.use(Optgroup) |
|
||||
.use(Option) |
|
||||
.use(Textarea) |
|
||||
.use(Button) |
|
||||
.use(Modal) |
|
||||
.use(List) |
|
||||
.use(Pulldown) |
|
||||
// 安装表格
|
|
||||
.use(Table); |
|
||||
} |
|
@ -0,0 +1,25 @@ |
|||||
|
import Layout from "/@/layout/index.vue"; |
||||
|
|
||||
|
const externalLink = { |
||||
|
path: "/external", |
||||
|
name: "external", |
||||
|
component: Layout, |
||||
|
meta: { |
||||
|
icon: "Link", |
||||
|
title: "message.externalLink", |
||||
|
showLink: true, |
||||
|
rank: 190 |
||||
|
}, |
||||
|
children: [ |
||||
|
{ |
||||
|
path: "https://github.com/xiaoxian521/vue-pure-admin", |
||||
|
meta: { |
||||
|
title: "message.externalLink", |
||||
|
showLink: true, |
||||
|
rank: 191 |
||||
|
} |
||||
|
} |
||||
|
] |
||||
|
}; |
||||
|
|
||||
|
export default externalLink; |
@ -0,0 +1,227 @@ |
|||||
|
.wave { |
||||
|
position: fixed; |
||||
|
height: 100%; |
||||
|
left: 0; |
||||
|
bottom: 0; |
||||
|
z-index: -1; |
||||
|
} |
||||
|
|
||||
|
.container { |
||||
|
width: 100vw; |
||||
|
height: 100vh; |
||||
|
display: grid; |
||||
|
grid-template-columns: repeat(2, 1fr); |
||||
|
grid-gap: 18rem; |
||||
|
padding: 0 2rem; |
||||
|
} |
||||
|
|
||||
|
.img { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.img img { |
||||
|
width: 500px; |
||||
|
} |
||||
|
|
||||
|
.login-box { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
.login-form { |
||||
|
width: 360px; |
||||
|
} |
||||
|
|
||||
|
.avatar { |
||||
|
width: 350px; |
||||
|
height: 80px; |
||||
|
} |
||||
|
|
||||
|
.login-form h2 { |
||||
|
text-transform: uppercase; |
||||
|
margin: 15px 0; |
||||
|
color: #999; |
||||
|
font: bold 200% Consolas, Monaco, monospace; |
||||
|
} |
||||
|
|
||||
|
.input-group { |
||||
|
position: relative; |
||||
|
display: grid; |
||||
|
grid-template-columns: 7% 93%; |
||||
|
margin: 25px 0; |
||||
|
padding: 5px 0; |
||||
|
border-bottom: 2px solid #d9d9d9; |
||||
|
} |
||||
|
|
||||
|
.input-group:nth-child(1) { |
||||
|
margin-bottom: 4px; |
||||
|
} |
||||
|
|
||||
|
.input-group::before, |
||||
|
.input-group::after { |
||||
|
content: ""; |
||||
|
position: absolute; |
||||
|
bottom: -2px; |
||||
|
width: 0; |
||||
|
height: 2px; |
||||
|
background-color: #c5d3f7; |
||||
|
transition: 0.5s; |
||||
|
} |
||||
|
|
||||
|
.input-group::after { |
||||
|
right: 50%; |
||||
|
} |
||||
|
|
||||
|
.input-group::before { |
||||
|
left: 50%; |
||||
|
} |
||||
|
|
||||
|
.icon { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.icon i { |
||||
|
color: #d9d9d9; |
||||
|
transition: 0.5s; |
||||
|
} |
||||
|
|
||||
|
.input-group > div { |
||||
|
position: relative; |
||||
|
height: 45px; |
||||
|
} |
||||
|
|
||||
|
.input-group > div > h5 { |
||||
|
position: absolute; |
||||
|
left: 10px; |
||||
|
top: 50%; |
||||
|
transform: translateY(-50%); |
||||
|
color: #d9d9d9; |
||||
|
font-size: 18px; |
||||
|
transition: 0.3s; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
} |
||||
|
|
||||
|
.input-group.focus .icon i { |
||||
|
color: #5392f0; |
||||
|
} |
||||
|
|
||||
|
.input-group.focus div h5 { |
||||
|
top: -5px; |
||||
|
font-size: 15px; |
||||
|
} |
||||
|
|
||||
|
.input-group.focus::after, |
||||
|
.input-group.focus::before { |
||||
|
width: 50%; |
||||
|
} |
||||
|
|
||||
|
.input { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
border: none; |
||||
|
outline: none; |
||||
|
background: none; |
||||
|
padding: 0.5rem 0.7rem; |
||||
|
font-size: 1.2rem; |
||||
|
color: #555; |
||||
|
font-family: "Roboto", sans-serif; |
||||
|
} |
||||
|
|
||||
|
a { |
||||
|
display: block; |
||||
|
text-align: right; |
||||
|
text-decoration: none; |
||||
|
color: #999; |
||||
|
font-size: 0.9rem; |
||||
|
transition: 0.3s; |
||||
|
} |
||||
|
|
||||
|
a:hover { |
||||
|
color: #5392f0; |
||||
|
} |
||||
|
|
||||
|
.btn { |
||||
|
display: block; |
||||
|
width: 100%; |
||||
|
height: 50px; |
||||
|
border-radius: 25px; |
||||
|
margin: 1rem 0; |
||||
|
font-size: 1.2rem; |
||||
|
outline: none; |
||||
|
border: none; |
||||
|
background-image: linear-gradient(to right, #567dbe, #5392f0, #567dbe); |
||||
|
cursor: pointer; |
||||
|
color: #fff; |
||||
|
text-transform: uppercase; |
||||
|
font-family: "Roboto", sans-serif; |
||||
|
background-size: 200%; |
||||
|
transition: 0.5s; |
||||
|
} |
||||
|
|
||||
|
.btn:hover { |
||||
|
background-position: right; |
||||
|
} |
||||
|
|
||||
|
.copyright { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
height: 50px; |
||||
|
bottom: 2px; |
||||
|
color: #5392f0; |
||||
|
text-align: center; |
||||
|
font-size: 18px; |
||||
|
font-family: "Roboto", sans-serif; |
||||
|
} |
||||
|
|
||||
|
@media screen and (max-width: 1080px) { |
||||
|
.container { |
||||
|
grid-gap: 9rem; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@media screen and (max-width: 1024px) { |
||||
|
.login-form { |
||||
|
width: 290px; |
||||
|
} |
||||
|
|
||||
|
.login-form h2 { |
||||
|
font-size: 2.4rem; |
||||
|
margin: 8px 0; |
||||
|
} |
||||
|
|
||||
|
.img img { |
||||
|
width: 360px; |
||||
|
} |
||||
|
|
||||
|
.avatar { |
||||
|
width: 280px; |
||||
|
height: 80px; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@media screen and (max-width: 768px) { |
||||
|
.wave { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.img { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
.container { |
||||
|
grid-template-columns: 1fr; |
||||
|
} |
||||
|
|
||||
|
.login-box { |
||||
|
justify-content: center; |
||||
|
} |
||||
|
} |
@ -1,20 +1,180 @@ |
|||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { reactive } from "vue"; |
|
||||
import info, { ContextProps } from "../components/ReInfo/index.vue"; |
|
||||
|
|
||||
const contextInfo: ContextProps = reactive({ |
|
||||
userName: "", |
|
||||
passWord: "", |
|
||||
verify: null, |
|
||||
svg: null |
|
||||
|
import { ref, computed } from "vue"; |
||||
|
import { useRouter } from "vue-router"; |
||||
|
import { initRouter } from "/@/router"; |
||||
|
import { storageSession } from "/@/utils/storage"; |
||||
|
import { addClass, removeClass } from "/@/utils/operate"; |
||||
|
import bg from "/@/assets/login/bg.png"; |
||||
|
import avatar from "/@/assets/login/avatar.svg"; |
||||
|
import illustration0 from "/@/assets/login/illustration0.svg"; |
||||
|
import illustration1 from "/@/assets/login/illustration1.svg"; |
||||
|
import illustration2 from "/@/assets/login/illustration2.svg"; |
||||
|
import illustration3 from "/@/assets/login/illustration3.svg"; |
||||
|
import illustration4 from "/@/assets/login/illustration4.svg"; |
||||
|
import illustration5 from "/@/assets/login/illustration5.svg"; |
||||
|
import illustration6 from "/@/assets/login/illustration6.svg"; |
||||
|
|
||||
|
const router = useRouter(); |
||||
|
|
||||
|
// eslint-disable-next-line vue/return-in-computed-property |
||||
|
const currentWeek = computed(() => { |
||||
|
switch (String(new Date().getDay())) { |
||||
|
case "0": |
||||
|
return illustration0; |
||||
|
case "1": |
||||
|
return illustration1; |
||||
|
case "2": |
||||
|
return illustration2; |
||||
|
case "3": |
||||
|
return illustration3; |
||||
|
case "4": |
||||
|
return illustration4; |
||||
|
case "5": |
||||
|
return illustration5; |
||||
|
case "6": |
||||
|
return illustration6; |
||||
|
default: |
||||
|
return illustration4; |
||||
|
} |
||||
}); |
}); |
||||
|
|
||||
// 登录 |
|
||||
const onLogin = () => {}; |
|
||||
|
let user = ref("admin"); |
||||
|
let pwd = ref("123456"); |
||||
|
|
||||
|
const onLogin = (): void => { |
||||
|
storageSession.setItem("info", { |
||||
|
username: "admin", |
||||
|
accessToken: "eyJhbGciOiJIUzUxMiJ9.test" |
||||
|
}); |
||||
|
initRouter("admin").then(() => {}); |
||||
|
router.push("/"); |
||||
|
}; |
||||
|
|
||||
|
function onUserFocus() { |
||||
|
addClass(document.querySelector(".user"), "focus"); |
||||
|
} |
||||
|
|
||||
|
function onUserBlur() { |
||||
|
if (user.value.length === 0) |
||||
|
removeClass(document.querySelector(".user"), "focus"); |
||||
|
} |
||||
|
|
||||
|
function onPwdFocus() { |
||||
|
addClass(document.querySelector(".pwd"), "focus"); |
||||
|
} |
||||
|
|
||||
|
function onPwdBlur() { |
||||
|
if (pwd.value.length === 0) |
||||
|
removeClass(document.querySelector(".pwd"), "focus"); |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
<template> |
<template> |
||||
<div class="login"> |
|
||||
<info :ruleForm="contextInfo" @on-behavior="onLogin" /> |
|
||||
|
<img :src="bg" class="wave" /> |
||||
|
<div class="container"> |
||||
|
<div class="img"> |
||||
|
<component :is="currentWeek"></component> |
||||
|
</div> |
||||
|
<div class="login-box"> |
||||
|
<div class="login-form"> |
||||
|
<avatar class="avatar" /> |
||||
|
<h2 |
||||
|
v-motion |
||||
|
:initial="{ |
||||
|
opacity: 0, |
||||
|
y: 100 |
||||
|
}" |
||||
|
:enter="{ |
||||
|
opacity: 1, |
||||
|
y: 0, |
||||
|
transition: { |
||||
|
delay: 100 |
||||
|
} |
||||
|
}" |
||||
|
> |
||||
|
Pure Admin |
||||
|
</h2> |
||||
|
<div |
||||
|
class="input-group user focus" |
||||
|
v-motion |
||||
|
:initial="{ |
||||
|
opacity: 0, |
||||
|
y: 100 |
||||
|
}" |
||||
|
:enter="{ |
||||
|
opacity: 1, |
||||
|
y: 0, |
||||
|
transition: { |
||||
|
delay: 200 |
||||
|
} |
||||
|
}" |
||||
|
> |
||||
|
<div class="icon"> |
||||
|
<i class="fa fa-user"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h5>用户名</h5> |
||||
|
<input |
||||
|
type="text" |
||||
|
class="input" |
||||
|
v-model="user" |
||||
|
@focus="onUserFocus" |
||||
|
@blur="onUserBlur" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
class="input-group pwd focus" |
||||
|
v-motion |
||||
|
:initial="{ |
||||
|
opacity: 0, |
||||
|
y: 100 |
||||
|
}" |
||||
|
:enter="{ |
||||
|
opacity: 1, |
||||
|
y: 0, |
||||
|
transition: { |
||||
|
delay: 300 |
||||
|
} |
||||
|
}" |
||||
|
> |
||||
|
<div class="icon"> |
||||
|
<i class="fa fa-lock"></i> |
||||
|
</div> |
||||
|
<div> |
||||
|
<h5>密码</h5> |
||||
|
<input |
||||
|
type="password" |
||||
|
class="input" |
||||
|
v-model="pwd" |
||||
|
@focus="onPwdFocus" |
||||
|
@blur="onPwdBlur" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<button |
||||
|
class="btn" |
||||
|
v-motion |
||||
|
:initial="{ |
||||
|
opacity: 0, |
||||
|
y: 10 |
||||
|
}" |
||||
|
:enter="{ |
||||
|
opacity: 1, |
||||
|
y: 0, |
||||
|
transition: { |
||||
|
delay: 400 |
||||
|
} |
||||
|
}" |
||||
|
@click="onLogin" |
||||
|
> |
||||
|
登录 |
||||
|
</button> |
||||
|
</div> |
||||
|
</div> |
||||
</div> |
</div> |
||||
</template> |
</template> |
||||
|
|
||||
|
<style scoped> |
||||
|
@import url("/@/style/login.css"); |
||||
|
</style> |
@ -1,17 +0,0 @@ |
|||||
<script setup lang="ts"> |
|
||||
import { reactive } from "vue"; |
|
||||
import info, { ContextProps } from "../components/ReInfo/index.vue"; |
|
||||
|
|
||||
const contextInfo: ContextProps = reactive({ |
|
||||
userName: "", |
|
||||
passWord: "", |
|
||||
verify: null, |
|
||||
svg: null |
|
||||
}); |
|
||||
</script> |
|
||||
|
|
||||
<template> |
|
||||
<div class="register"> |
|
||||
<info :ruleForm="contextInfo" /> |
|
||||
</div> |
|
||||
</template> |
|