fix: 完成 login 页面

This commit is contained in:
MTrun 2021-12-15 14:25:28 +08:00
parent c4caff75e4
commit ed49e4add8
27 changed files with 155 additions and 43 deletions

View File

@ -29,6 +29,7 @@
"eslint-plugin-import": "^2.25.3", "eslint-plugin-import": "^2.25.3",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.2.0", "eslint-plugin-vue": "^8.2.0",
"lodash": "^4.17.21",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"sass": "^1.43.2", "sass": "^1.43.2",
"sass-loader": "^12.2.0", "sass-loader": "^12.2.0",

2
pnpm-lock.yaml generated
View File

@ -15,6 +15,7 @@ specifiers:
eslint-plugin-import: ^2.25.3 eslint-plugin-import: ^2.25.3
eslint-plugin-prettier: ^4.0.0 eslint-plugin-prettier: ^4.0.0
eslint-plugin-vue: ^8.2.0 eslint-plugin-vue: ^8.2.0
lodash: ^4.17.21
mockjs: ^1.1.0 mockjs: ^1.1.0
naive-ui: ^2.19.9 naive-ui: ^2.19.9
pinia: ^2.0.6 pinia: ^2.0.6
@ -52,6 +53,7 @@ devDependencies:
eslint-plugin-import: rg.cnpmjs.org/eslint-plugin-import/2.25.3_eslint@8.4.1 eslint-plugin-import: rg.cnpmjs.org/eslint-plugin-import/2.25.3_eslint@8.4.1
eslint-plugin-prettier: rg.cnpmjs.org/eslint-plugin-prettier/4.0.0_90bd2ba582f6d1348d73031482d782e2 eslint-plugin-prettier: rg.cnpmjs.org/eslint-plugin-prettier/4.0.0_90bd2ba582f6d1348d73031482d782e2
eslint-plugin-vue: rg.cnpmjs.org/eslint-plugin-vue/8.2.0_eslint@8.4.1 eslint-plugin-vue: rg.cnpmjs.org/eslint-plugin-vue/8.2.0_eslint@8.4.1
lodash: rg.cnpmjs.org/lodash/4.17.21
prettier: rg.cnpmjs.org/prettier/2.5.1 prettier: rg.cnpmjs.org/prettier/2.5.1
sass: rg.cnpmjs.org/sass/1.44.0 sass: rg.cnpmjs.org/sass/1.44.0
sass-loader: rg.cnpmjs.org/sass-loader/12.4.0_sass@1.44.0 sass-loader: rg.cnpmjs.org/sass-loader/12.4.0_sass@1.44.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 34 KiB

0
src/hooks/index.ts Normal file
View File

View File

@ -1,6 +1,7 @@
import type { App } from 'vue'; import type { App } from 'vue';
import { import {
create, create,
NA,
NConfigProvider, NConfigProvider,
NMessageProvider, NMessageProvider,
NDialogProvider, NDialogProvider,
@ -67,11 +68,13 @@ import {
NBackTop, NBackTop,
NSkeleton, NSkeleton,
NCarousel, NCarousel,
NScrollbar,
NCollapseTransition NCollapseTransition
} from 'naive-ui'; } from 'naive-ui';
const naive = create({ const naive = create({
components: [ components: [
NA,
NMessageProvider, NMessageProvider,
NDialogProvider, NDialogProvider,
NConfigProvider, NConfigProvider,
@ -138,6 +141,7 @@ const naive = create({
NBackTop, NBackTop,
NSkeleton, NSkeleton,
NCarousel, NCarousel,
NScrollbar,
NCollapseTransition NCollapseTransition
], ],
}); });

View File

@ -31,3 +31,6 @@ export const theme = {
// 修改边框圆角 // 修改边框圆角
export const borderRadius = '8px' export const borderRadius = '8px'
// 轮播间隔
export const carouselInterval = 5000

View File

@ -1,3 +1,4 @@
// 淡入淡出
.v-modal-enter { .v-modal-enter {
animation: v-modal-in 0.2s ease; animation: v-modal-in 0.2s ease;
} }
@ -21,3 +22,16 @@
opacity: 0; opacity: 0;
} }
} }
// 移动动画
.list-complete-item {
transition: all 1s;
}
.list-complete-enter,
.list-complete-leave-to {
opacity: 0;
transform: translateY(30px);
}
.list-complete-leave-active {
position: absolute;
}

View File

@ -10,6 +10,7 @@ $--color-text-2: hsla(0, 0%, 100%, 0.7);
$--color-text-3: hsla(0, 0%, 100%, 0.5); $--color-text-3: hsla(0, 0%, 100%, 0.5);
$--color-text-4: hsla(0, 0%, 100%, 0.3); $--color-text-4: hsla(0, 0%, 100%, 0.3);
$--max-width: 1920px;
// 顶部距离 // 顶部距离
$--header-height: 60px; $--header-height: 60px;
// 模糊 // 模糊

View File

@ -13,12 +13,18 @@ export function getUUID(randomLength: number) {
).toString(36); ).toString(36);
} }
/** /**
* * render * * render
*/ */
export const renderIcon = (icon: any) => { export const renderIcon = (icon: typeof NIcon) => {
return () => h(NIcon, null, { default: () => h(icon) }); return () => h(NIcon, null, { default: () => h(icon) });
} }
/**
* * vite 使 require
* @param name
* @returns
*/
export const requireUrl = (path: string, name: string) => {
return new URL(`${path}/${name}`, import.meta.url).href
}

View File

@ -1,15 +1,29 @@
<template> <template>
<div class="go-login-box"> <div class="go-login-box">
<div class="go-login-box-bg"></div> <div class="go-login-box-bg">
<aside class="bg-slot"></aside>
<aside class="bg-img-box">
<transition-group name="list-complete">
<template v-for="item in bgList" :key="item">
<div class="bg-img-box-li list-complete-item">
<n-collapse-transition :appear="true" :show="show">
<img :src="getImageUrl(item, 'chart')" alt="chart" />
</n-collapse-transition>
</div>
</template>
</transition-group>
</aside>
</div>
<n-divider class="go-login-box-header" /> <n-divider class="go-login-box-header" />
<div class="go-login"> <div class="go-login">
<div class="go-login-carousel"> <div class="go-login-carousel">
<n-carousel autoplay> <n-carousel autoplay :interval="Number(carouselInterval)">
<img <img
v-for="(e, i) in imgList" v-for="(item, i) in carouselImgList"
:key="i" :key="i"
class="go-login-carousel-img" class="go-login-carousel-img"
:src="e" :src="getImageUrl(item, 'login')"
alt="展示图片" alt="展示图片"
/> />
</n-carousel> </n-carousel>
@ -84,26 +98,31 @@
</div> </div>
</div> </div>
</div> </div>
<div class="go-login-box-footer"> <div class="go-login-box-footer">
文档地址: http://www.mtruning.club/ <n-a>文档地址: </n-a>
<n-a italic href="http://www.mtruning.club/">
http://www.mtruning.club/
</n-a>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { reactive, ref, onMounted } from 'vue' import { reactive, ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useMessage } from 'naive-ui' import { useMessage } from 'naive-ui'
import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5' import { PersonOutline, LockClosedOutline } from '@vicons/ionicons5'
import imgOne from '@/assets/images/login/one.png' import { requireUrl } from '@/utils/index'
import imgTwo from '@/assets/images/login/two.png' import { shuffle } from 'lodash'
import imgThree from '@/assets/images/login/three.png' import { carouselInterval } from '@/settings/designSetting'
interface FormState { interface FormState {
username: string username: string
password: string password: string
} }
const router = useRouter()
const formRef = ref() const formRef = ref()
const message = useMessage() const message = useMessage()
const loading = ref(false) const loading = ref(false)
@ -126,11 +145,38 @@ const rules = {
password: { required: true, message: '请输入密码', trigger: 'blur' } password: { required: true, message: '请输入密码', trigger: 'blur' }
} }
const imgList = [imgOne, imgTwo, imgThree] //
const shuffleTimiing = ref()
const router = useRouter() //
const route = useRoute() const carouselImgList = ['one', 'two', 'three']
//
const bgList = ref([
'bar_y',
'bar_x',
'line_gradient',
'line',
'funnel',
'heatmap',
'map',
'pie',
'radar',
])
// url
const getImageUrl = (name: string, folder: string) => {
return requireUrl(`../assets/images/${folder}`, `${name}.png`)
}
//
const shuffleHandle = () => {
shuffleTimiing.value = setInterval(() => {
bgList.value = shuffle(bgList.value)
}, carouselInterval)
}
//
const handleSubmit = (e: Event) => { const handleSubmit = (e: Event) => {
e.preventDefault() e.preventDefault()
formRef.value.validate(async (errors: any) => { formRef.value.validate(async (errors: any) => {
@ -145,55 +191,67 @@ const handleSubmit = (e: Event) => {
} }
}) })
} }
onMounted(() => {
shuffleHandle()
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
$width: 450px; $width: 450px;
$go-login-height: 100vh;
$account-img-height: 270px; $account-img-height: 270px;
$footer-height: 50px; $footer-height: 50px;
$account-height: calc(100vh - $footer-height); $carousel-width: 30%;
$--filter-color-base-login: rgba(51, 55, 61, 0.3); $carousel-image-height: 60vh;
$--filter-color-base-login: rgba(89, 95, 103, 0.45);
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
@include go(login-box) { @include go(login-box) {
height: 100vh; height: $go-login-height;
overflow: hidden; overflow: hidden;
background-image: linear-gradient(120deg, $--color-bg-1 0%, $--color-bg-2 100%); background-image: linear-gradient(
120deg,
$--color-bg-1 0%,
$--color-bg-2 100%
);
&-header { &-header {
margin: 0px; margin: 0px;
padding-top: $--header-height; padding-top: $--header-height;
} }
@include go(login) { @include go(login) {
z-index: 2;
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-around;
align-items: center; align-items: center;
margin-top: -$--header-height; margin-top: -$--header-height;
padding-top: $--header-height; height: $go-login-height;
max-width: $--max-width;
&-carousel { &-carousel {
width: 50%; width: $carousel-width;
margin-top: 100px;
min-width: 500px;
&-img { &-img {
height: 70vh; display: block;
margin: 0 auto;
height: $carousel-image-height;
} }
} }
.login-account { .login-account {
z-index: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: $account-height; margin: 0 160px;
&-container { &-container {
flex: 1;
padding: 32px 0;
width: $width; width: $width;
margin: 0 auto;
margin-top: 100px;
} }
&-card { &-card {
@extend .go-background-filter; @extend .go-background-filter;
background-color: $--filter-color-base-login; background-color: $--filter-color-base-login;
box-shadow: 0 0 105px 50px #202020;
} }
&-top { &-top {
@ -206,8 +264,11 @@ $--filter-color-base-login: rgba(51, 55, 61, 0.3);
} }
&-footer { &-footer {
z-index: 2;
position: fixed;
bottom: 0;
width: 100%;
height: $footer-height; height: $footer-height;
margin-top: -$--header-height;
text-align: center; text-align: center;
line-height: $footer-height; line-height: $footer-height;
color: $--color-text-2; color: $--color-text-2;
@ -216,21 +277,41 @@ $--filter-color-base-login: rgba(51, 55, 61, 0.3);
&-bg { &-bg {
z-index: 0; z-index: 0;
position: fixed; position: fixed;
width: 100vw; display: flex;
justify-content: space-around;
align-items: center;
width: $--max-width;
height: 100vh; height: 100vh;
background: url('@/assets/images/login/login-bg.png') no-repeat 750px -120px; background: url('@/assets/images/login/login-bg.png') no-repeat 0 -120px;
.bg-slot{
width: $carousel-width;
}
.bg-img-box {
position: relative;
display: flex;
flex-wrap: wrap;
width: 770px;
margin-right: -20px;
&-li {
img {
margin-right: 20px;
margin-top: 20px;
height: 230px;
border-radius: 2 * $--border-radius-base;
opacity: 0.9;
} }
@media (min-width: 768px) {
.login-account {
background-repeat: no-repeat;
background-position: 50%;
background-size: 100%;
} }
.page-account-container {
padding: 32px 0 24px 0;
} }
} }
} }
@media only screen and (max-width: 1200px) {
.bg-img-box,
.bg-slot,
.go-login-carousel {
display: none !important;
}
.go-login-box-footer {
position: relative;
}
}
</style> </style>