优化Gallery页面滚动加载和布局,调整菜单项命名,添加Apps页面,更新依赖声明
This commit is contained in:
1
extra.d.ts
vendored
1
extra.d.ts
vendored
@ -3,3 +3,4 @@ declare module "vue3-video-play";
|
||||
declare module "vue3-masonry-plus";
|
||||
declare module "vite";
|
||||
declare module "vue-devui/tag";
|
||||
declare module "vue-infinite-scroll";
|
||||
@ -96,27 +96,27 @@ const menuOptions = ref([
|
||||
icon: () => h(homeSvg)
|
||||
},
|
||||
{
|
||||
label: () => h(RouterLink, { to: '/gallery', class: 'flex items-center justify-center' }, { default: () => '画廊管理' }),
|
||||
label: () => h(RouterLink, { to: '/gallery', class: 'flex items-center justify-center' }, { default: () => '画廊' }),
|
||||
key: "gallery",
|
||||
icon: () => h(picSvg)
|
||||
},
|
||||
{
|
||||
label: () => h(RouterLink, { to: '/blog', class: 'flex items-center justify-center' }, { default: () => '文章管理' }),
|
||||
label: () => h(RouterLink, { to: '/blog', class: 'flex items-center justify-center' }, { default: () => '文章' }),
|
||||
key: "blog",
|
||||
icon: () => h(artiSvg)
|
||||
},
|
||||
{
|
||||
label: () => h(RouterLink, { to: '/widget', class: 'flex items-center justify-center' }, { default: () => '工具管理' }),
|
||||
label: () => h(RouterLink, { to: '/widget', class: 'flex items-center justify-center' }, { default: () => '工具' }),
|
||||
key: "widget",
|
||||
icon: () => h(downSvg)
|
||||
},
|
||||
{
|
||||
label: () => h(RouterLink, { to: '/apps', class: 'flex items-center justify-center' }, { default: () => '软件管理' }),
|
||||
label: () => h(RouterLink, { to: '/apps', class: 'flex items-center justify-center' }, { default: () => '软件' }),
|
||||
key: "apps",
|
||||
icon: () => h(settingSvg)
|
||||
},
|
||||
{
|
||||
label: () => h(RouterLink, { to: '/plink', class: 'flex items-center justify-center' }, { default: () => '友链管理' }),
|
||||
label: () => h(RouterLink, { to: '/plink', class: 'flex items-center justify-center' }, { default: () => '友链' }),
|
||||
key: "plink",
|
||||
icon: () => h(linkSvg)
|
||||
},
|
||||
@ -147,7 +147,7 @@ function handleSelect(key: string) {
|
||||
return
|
||||
}
|
||||
if (key == 'console') {
|
||||
router.push('/console')
|
||||
gotoConsole()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="image-container">
|
||||
<div class="image-container flex justify-center items-center">
|
||||
<n-image ref="lazyRef" class="lazy__img" :src="url" @load="handleLoad" @error="handleError">
|
||||
<template #placeholder>
|
||||
<img :src="loading" alt="loading" />
|
||||
<img width="400" :src="loading" alt="loading" />
|
||||
</template>
|
||||
<template #error>
|
||||
<img :src="errorImg" alt="error" />
|
||||
@ -62,7 +62,7 @@ onMounted(() => {
|
||||
|
||||
.lazy__img img[alt="loading"],
|
||||
.lazy__img img[alt="error"] {
|
||||
width: 48px;
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
padding: 1em;
|
||||
margin: 0 auto;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
definePage({
|
||||
name:'appshare',
|
||||
name:'apps',
|
||||
meta: {
|
||||
title: '软件分享',
|
||||
}
|
||||
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<!-- <PerfectScrollbar ref="scrollbar" @ps-scroll-y="handleScroll"> -->
|
||||
<div ref="myCon" class="py-5 px-[10%]">
|
||||
<n-input class="my-4 !w-[90%] ml-[5%]" round size="large" v-model:value="kw" @keyup.enter="onSearch"
|
||||
<n-scrollbar ref="virtualListInst" class="py-5" :style="boxStyle" @scroll="handleScroll">
|
||||
<n-input class="my-4 !w-[72%] ml-[14%]" round size="large" v-model:value="kw" @keyup.enter="onSearch"
|
||||
placeholder="请输入关键字">
|
||||
<template #suffix>
|
||||
<n-icon size="large">
|
||||
@ -10,12 +9,11 @@
|
||||
</template>
|
||||
</n-input>
|
||||
|
||||
<!-- <div v-infinite-scroll="loadMore"> -->
|
||||
<Waterfall ref="waterfall" :list="fileList" :gutter="gutter" :columns="column" img-selector="url"
|
||||
<Waterfall class="ml-[10%] !w-[80%]" ref="waterfall" :list="fileList" :gutter="gutter" :columns="column" img-selector="url"
|
||||
animation-effect="fadeIn" :animation-duration="1000" :animation-delay="300" backgroundColor="transparent"> >
|
||||
<template #item="{ item }">
|
||||
<div
|
||||
class="card rounded-md overflow-hidden group transition-transform duration-300 box-border hover:-translate-y-1.5">
|
||||
class="card rounded-md shadow-lg overflow-hidden group transition-transform duration-300 box-border hover:-translate-y-1.5">
|
||||
<!-- <div class="image-wrapper"> -->
|
||||
<LazyImg class="rounded-md shadow overflow-hidden" :url="item.filepath" />
|
||||
<!-- </div> -->
|
||||
@ -24,17 +22,14 @@
|
||||
{{ item.filename }}
|
||||
</div>
|
||||
<div
|
||||
class="absolute rounded-md flex z-10 truncate bottom-2 w-full bg-[#00000070] text-white justify-between items-center">
|
||||
class="absolute rounded-md flex z-10 truncate bottom-0 w-full bg-[#00000070] text-white justify-between items-center">
|
||||
<div>由 <span class="text-[#f1d9db] font-600">{{ item.nickname }}</span> 分享</div>
|
||||
<icon-download class="cursor-pointer w-4 h-4" @click="downloadFile(item.filepath)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Waterfall>
|
||||
</div>
|
||||
<!-- </div> -->
|
||||
<!-- </PerfectScrollbar> -->
|
||||
|
||||
</n-scrollbar>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@ -46,23 +41,24 @@ definePage({
|
||||
title: '画廊',
|
||||
}
|
||||
})
|
||||
declare module "vue" {
|
||||
interface HTMLAttributes {
|
||||
"v-infinite-scroll"?: () => void;
|
||||
}
|
||||
}
|
||||
const waterfall = ref<any>(null);
|
||||
|
||||
const nav: any = $store.nav.useNavStore()
|
||||
const boxStyle: any = ref({})
|
||||
// 画廊页逻辑
|
||||
const fileList = ref<any[]>([]);
|
||||
const pn = ref(1);
|
||||
const ps = ref(40);
|
||||
const ps = ref(20);
|
||||
const loading = ref(false);
|
||||
const kw = ref<string>('');
|
||||
const cwidth = ref<number>(240);
|
||||
const column = ref<number>(5);
|
||||
const gutter = ref<number>(18);
|
||||
|
||||
const isLoadAll = ref<boolean>(false)
|
||||
|
||||
|
||||
|
||||
|
||||
// 计算列数
|
||||
function calculateColumns() {
|
||||
const totalWidth = window.innerWidth * 0.8; // 画廊宽度为视口宽度的80%
|
||||
@ -82,7 +78,9 @@ async function getFileList() {
|
||||
page_size: ps.value,
|
||||
});
|
||||
// console.log('>>> --> getFileList --> res:', res);
|
||||
|
||||
if (res.data.length < ps.value) {
|
||||
isLoadAll.value = true;
|
||||
}
|
||||
if (pn.value === 1) {
|
||||
fileList.value = res.data;
|
||||
} else {
|
||||
@ -104,6 +102,7 @@ async function getFileList() {
|
||||
const handleScroll: any = throttle((e: any) => {
|
||||
// console.log('>>> --> handleScroll --> loading:', e)
|
||||
if (loading.value) return;
|
||||
if (isLoadAll.value) return;
|
||||
const scrollTop = e.target.scrollTop
|
||||
// console.log('>>> --> handleScroll --> scrollTop:', scrollTop)
|
||||
const scrollHeight = e.target.scrollHeight
|
||||
@ -112,7 +111,7 @@ const handleScroll: any = throttle((e: any) => {
|
||||
|
||||
// 当滚动到距离底部20%时加载更多
|
||||
// console.log('>>> --> clientHeight --> clientHeight:', clientHeight)
|
||||
if (scrollTop + clientHeight >= scrollHeight * 0.8) {
|
||||
if (scrollTop + clientHeight >= scrollHeight - 100) {
|
||||
console.log('>>> --> handleScroll --> 加载更多')
|
||||
pn.value++;
|
||||
getFileList();
|
||||
@ -120,6 +119,8 @@ const handleScroll: any = throttle((e: any) => {
|
||||
}, 1000)
|
||||
function onSearch() {
|
||||
pn.value = 1;
|
||||
kw.value = kw.value.trim()
|
||||
isLoadAll.value = false
|
||||
getFileList();
|
||||
}
|
||||
|
||||
@ -146,6 +147,10 @@ function downloadFile(url: string) {
|
||||
onMounted(() => {
|
||||
calculateColumns()
|
||||
getFileList();
|
||||
console.log('>>> --> nav.NavH:', nav.navH)
|
||||
boxStyle.value = {
|
||||
maxHeight: `calc(100vh - 5px - ${nav.navH}px)`,
|
||||
}
|
||||
// 添加滚动监听
|
||||
window.addEventListener('resize', calculateColumns);
|
||||
window.addEventListener('scroll', handleScroll);
|
||||
@ -155,6 +160,7 @@ onUnmounted(() => {
|
||||
pn.value = 1;
|
||||
kw.value = '';
|
||||
fileList.value = [];
|
||||
isLoadAll.value = false
|
||||
// 移除监听
|
||||
window.removeEventListener('scroll', handleScroll);
|
||||
});
|
||||
@ -162,10 +168,6 @@ onUnmounted(() => {
|
||||
|
||||
<style scoped lang="less">
|
||||
:deep(.n-image img) {
|
||||
--un-shadow: var(--un-shadow-inset) 0 1px 3px 0 var(--un-shadow-color, rgb(0 0 0 / 0.1)),
|
||||
var(--un-shadow-inset) 0 1px 2px -1px var(--un-shadow-color, rgb(0 0 0 / 0.1));
|
||||
box-shadow: var(--un-ring-offset-shadow), var(--un-ring-shadow),
|
||||
var(--un-shadow);
|
||||
border-radius: 0.375rem !important;
|
||||
}
|
||||
</style>
|
||||
6
typed-router.d.ts
vendored
6
typed-router.d.ts
vendored
@ -18,7 +18,7 @@ declare module 'vue-router/auto-routes' {
|
||||
* Route name map generated by unplugin-vue-router
|
||||
*/
|
||||
export interface RouteNamedMap {
|
||||
'appshare': RouteRecordInfo<'appshare', '/AppShare', Record<never, never>, Record<never, never>>,
|
||||
'apps': RouteRecordInfo<'apps', '/Apps', Record<never, never>, Record<never, never>>,
|
||||
'blog': RouteRecordInfo<'blog', '/Blog', Record<never, never>, Record<never, never>>,
|
||||
'gallery': RouteRecordInfo<'gallery', '/Gallery', Record<never, never>, Record<never, never>>,
|
||||
'home': RouteRecordInfo<'home', '/Home', Record<never, never>, Record<never, never>>,
|
||||
@ -38,8 +38,8 @@ declare module 'vue-router/auto-routes' {
|
||||
* @internal
|
||||
*/
|
||||
export interface _RouteFileInfoMap {
|
||||
'src/views/AppShare.vue': {
|
||||
routes: 'appshare'
|
||||
'src/views/Apps.vue': {
|
||||
routes: 'apps'
|
||||
views: never
|
||||
}
|
||||
'src/views/Blog.vue': {
|
||||
|
||||
@ -8,7 +8,7 @@ import Components from "unplugin-vue-components/vite";
|
||||
import { VueRouterAutoImports } from "unplugin-vue-router";
|
||||
import VueRouter from "unplugin-vue-router/vite";
|
||||
import { defineConfig } from "vite";
|
||||
import vueDevTools from "vite-plugin-vue-devtools";
|
||||
// import vueDevTools from "vite-plugin-vue-devtools";
|
||||
import svgLoader from "vite-svg-loader";
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig({
|
||||
@ -36,7 +36,7 @@ export default defineConfig({
|
||||
}),
|
||||
UnoCSS(),
|
||||
svgLoader(),
|
||||
vueDevTools(),
|
||||
// vueDevTools(),
|
||||
],
|
||||
esbuild: {
|
||||
pure: ["console.log"], // 删除 console.log
|
||||
|
||||
Reference in New Issue
Block a user