feat: 添加NProgress加载进度条和优化UI样式
添加NProgress依赖并集成到路由中,实现页面切换时的加载进度条 优化友链页面、博客分类和文章列表的UI样式 调整登录按钮和图片懒加载的显示效果 新增标签随机颜色功能,提升视觉体验
This commit is contained in:
+48
-18
@@ -4,7 +4,7 @@
|
||||
<n-card class="card w-100 shadow">
|
||||
<template #header>
|
||||
<div class="flex items-center gap-4 text-primary text-xl font-bold">
|
||||
<icon-loading class="zhuan text-primary w-6 h-6" />
|
||||
<icon-loading class="zhuan text-primary w-6 h-6" />
|
||||
申请友链
|
||||
</div>
|
||||
</template>
|
||||
@@ -54,8 +54,8 @@
|
||||
站点介绍
|
||||
</div>
|
||||
</template>
|
||||
<n-input type="textarea" :autosize="{ minRows: 2, maxRows: 3 }" maxlength="50" v-model:value="plinkData.desc"
|
||||
placeholder="请用一句话简短的描述你的站点" />
|
||||
<n-input type="textarea" :autosize="{ minRows: 2, maxRows: 3 }" maxlength="50"
|
||||
v-model:value="plinkData.desc" placeholder="请用一句话简短的描述你的站点" />
|
||||
</n-form-item>
|
||||
<n-form-item path="tagname">
|
||||
<template #label>
|
||||
@@ -64,8 +64,8 @@
|
||||
标签
|
||||
</div>
|
||||
</template>
|
||||
<n-input type="textarea" :autosize="{ minRows: 2, maxRows: 3 }" maxlength="50" v-model:value="plinkData.tagname"
|
||||
placeholder="输入你的标签,用逗号隔开,注意每个标签最多3个字符,且只显示前3个标签哦~" />
|
||||
<n-input type="textarea" :autosize="{ minRows: 2, maxRows: 3 }" maxlength="50"
|
||||
v-model:value="plinkData.tagname" placeholder="输入你的标签,用逗号隔开,注意每个标签最多3个字符,且只显示前3个标签哦~" />
|
||||
</n-form-item>
|
||||
<n-form-item>
|
||||
<n-button class="w-full" type="primary" @click="submitPut">申请友链</n-button>
|
||||
@@ -83,13 +83,16 @@
|
||||
<div class="ava">
|
||||
<n-avatar round size="large" :src="p.avater"></n-avatar>
|
||||
</div>
|
||||
<div class="text-primary">
|
||||
<em class="bg-[#fbf2e3] px-4 rounded-full text-sm text-primary mb-4">{{ p.name }}</em>
|
||||
<div class="font-bold text-xl text-gray-700 mb-1">
|
||||
{{ p.title }}
|
||||
</div>
|
||||
<em class="text-gray-400 text-sm">{{ p.name }}</em>
|
||||
<div class="flex gap-1 truncate">
|
||||
<div v-for="i in getTags(p.tagname)" :key="i.tid" class="flex items-center gap-1 text-deepp text-sm">
|
||||
<icon-tag2 class="w-3 h-3 !text-deepp" />{{ i }}
|
||||
|
||||
<div class="flex gap-1 truncate mb-1 text-sm">
|
||||
<div v-for="i in getTags(p.tagname)" :key="i.tid"
|
||||
:style="{ backgroundColor: getDictValue(tagColorList, 'tag', i, 'color') }"
|
||||
class="flex items-center gap-1 cursor-pointer text-sm text-white rounded-full px-3">
|
||||
<icon-tag2 class="w-3 h-3 " />{{ i }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="truncate w-full text-gray-400 text-sm text-center">
|
||||
@@ -108,7 +111,7 @@ import siteIcon from '@/icon/plink/site.svg';
|
||||
import tagIcon from '@/icon/plink/tag.svg';
|
||||
import urlIcon from '@/icon/plink/uri.svg';
|
||||
import userIcon from '@/icon/plink/user.svg';
|
||||
|
||||
import { getDictValue } from '@/util';
|
||||
|
||||
definePage({
|
||||
name: 'plink',
|
||||
@@ -137,18 +140,32 @@ const rules: any = {
|
||||
}
|
||||
const pList = ref<any>([])
|
||||
const formRef = ref<any>(null)
|
||||
const tagColorList: any = ref([])
|
||||
async function getPlinkList() {
|
||||
const res = await $http.plink.getPlinkList()
|
||||
|
||||
const list: Array<string> = []
|
||||
// 对res.data.tags进行去重
|
||||
res.data.forEach((i: any) => {
|
||||
const t = getTags(i.tagname)
|
||||
t.forEach((ii: string) => {
|
||||
if (!list.includes(ii)) list.push(ii)
|
||||
})
|
||||
});
|
||||
|
||||
tagColorList.value = list.map((i: string) => {
|
||||
return {
|
||||
tag: i,
|
||||
color: getRandomFromPalette()
|
||||
}
|
||||
})
|
||||
pList.value = res.data
|
||||
// for (let i = 0; i < 20; i++) {
|
||||
// pList.value.push(res.data[0])
|
||||
// }
|
||||
}
|
||||
function getTags(str: any) {
|
||||
str = str.replaceAll(',', ',')
|
||||
let tags = str.split(',').slice(0, 3)
|
||||
tags.forEach((tag: any, idx: number) => {
|
||||
tags[idx] = tag.trim().slice(0, 3)
|
||||
tags[idx] = tag.trim().slice(0, 4)
|
||||
});
|
||||
return tags
|
||||
}
|
||||
@@ -178,7 +195,23 @@ function submitPut() {
|
||||
})
|
||||
}
|
||||
|
||||
// 生成一个随机的鲜艳颜色,和白色能对比
|
||||
|
||||
function getRandomFromPalette(): string {
|
||||
const hue = Math.floor(Math.random() * 360);
|
||||
return hslToHex(hue, 80, 50);
|
||||
}
|
||||
|
||||
function hslToHex(h: number, s: number, l: number): any {
|
||||
l /= 100;
|
||||
const a = s * Math.min(l, 1 - l) / 100;
|
||||
const f = (n: number) => {
|
||||
const k = (n + h / 30) % 12;
|
||||
const color = l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1);
|
||||
return Math.round(255 * color).toString(16).padStart(2, '0');
|
||||
}
|
||||
return `#${f(0)}${f(8)}${f(4)}`;
|
||||
}
|
||||
onMounted(() => {
|
||||
boxStyle.value = {
|
||||
height: window.innerHeight - nav.navH - 1 + 'px',
|
||||
@@ -197,11 +230,8 @@ onMounted(() => {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
.zhuan {
|
||||
animation: spin 1.5s linear infinite;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user