迁移UI框架至naive-ui,重构组件和样式,添加Gallery和Mask组件

This commit is contained in:
2025-12-28 16:45:58 +08:00
parent 4c097e4c40
commit 96edada2ff
54 changed files with 2482 additions and 2979 deletions

281
src/components/Gallery.vue Normal file
View File

@ -0,0 +1,281 @@
<template>
<PerfectScrollbar ref="scrollbar" @ps-scroll-y="handleScroll">
<div ref="myCon" class="gallery-page py-5 px-[10%]">
<d-search class="mt-0 mb-8 w-2/3 mx-auto rounded-full" v-model="kw" is-keyup-search :delay="1000"
@search="onSearch"></d-search>
<div class="gallery-container w-full box-border">
<!-- 瀑布流容器 -->
<div ref="waterfallContainer" v-image-preview
class="waterfall-container flex justify-between flex-nowrap w-full overflow-hidden">
<!-- 动态生成的列 -->
<div v-for="(column, index) in columns" :key="index" class="waterfall-column flex flex-col w-[240px]">
<div v-for="item in column" :key="item.id"
class="gallery-item group relative my-[10px] rounded-lg overflow-hidden transition-transform duration-300 box-border hover:-translate-y-1.5">
<div
class="absolute px-2 truncate hidden group-hover:block top-0 text-center w-full bg-[#00000070] text-white">
{{ item.filename }}</div>
<img :src="item.filepath" alt="" class="gallery-image block w-full h-auto object-cover rounded-md">
<div class="px-2 absolute bottom-0 flex justify-between w-full bg-[#00000060]">
<div class="text-white "> <span class="text-[#f1d9db] font-600">{{ item.nickname }}</span> 上传</div>
<d-popover content="下载" trigger="hover" class="!bg-primary" style="color: #fff">
<icon-download @click="downloadFile(item.filepath)"
class="w-5 h-5 text-white hover-text-primary"></icon-download>
</d-popover>
</div>
</div>
</div>
</div>
<!-- 加载中指示器 -->
<div v-if="loading" class="loading-indicator text-center p-5 text-gray-600">加载中...</div>
<div v-else class="loading-indicator text-center p-5 text-gray-600">已全部加载完成</div>
</div>
</div>
</PerfectScrollbar>
</template>
<script setup lang="ts">
import { throttle } from 'es-toolkit';
definePage({
name: 'gallery',
meta: {
title: '画廊',
}
})
// 画廊页逻辑
const fileList = ref<any[]>([]);
const pn = ref(1);
const ps = ref(40);
const loading = ref(false);
const waterfallContainer = ref<HTMLDivElement | null>(null);
const columns = ref<Array<Array<any>>>([]);
const columnHeights = ref<number[]>([]);
const columnCount = ref(4); // 默认列数
const itemWidth = ref(240); // 图片宽度固定为240px
const kw = ref<string>('');
// const uploadOptions = ref({
// uri: 'https://www.hxyouzi.com/api/files/upload',
// method: 'POST',
// maximumSize: 5 * 1024 * 1024,
// headers: {
// 'Authorization': 'Bearer ' + $cookies.get('token'),
// },
// });
// 计算列数 based on 屏幕宽度
function calculateColumnCount() {
if (!waterfallContainer.value) return;
const containerWidth = waterfallContainer.value.clientWidth;
const newColumnCount = Math.max(1, Math.floor(containerWidth / itemWidth.value));
if (newColumnCount !== columnCount.value) {
columnCount.value = newColumnCount;
resetWaterfall();
}
}
// 重置瀑布流
function resetWaterfall() {
columns.value = Array(columnCount.value).fill(0).map(() => []);
columnHeights.value = Array(columnCount.value).fill(0);
// 重新分配图片
fileList.value.forEach(async (item:any) =>await addToWaterfall(item));
console.log('>>> --> resetWaterfall --> fileList:', fileList.value)
}
// 添加图片到瀑布流
async function addToWaterfall(item: any) {
if (columns.value.length === 0) return;
const { height, width } =await getImageSizeByCheck(item.filepath)
// 找到高度最小的列
let minHeight = Math.min(...columnHeights.value);
let minIndex = columnHeights.value.indexOf(minHeight);
console.log('>>> --> addToWaterfall --> item:', item)
console.log('>>> --> addToWaterfall --> minIndex:', minIndex)
// 添加到该列
columns.value[minIndex].push(item);
// 估算列高 - 实际高度会在图片加载后更新
const estimatedHeight = itemWidth.value * height / width
columnHeights.value[minIndex] += estimatedHeight + 20; // 加上padding和margin
}
function getImageSizeByCheck(url: string): any {
return new Promise(function (resolve, reject) {
let image = new Image();
image.src = url;
let height = 0
let width = 0
// let timer = setTimeout(() => {
image.onload = () => {
if (image.width > 0 && image.height > 0) {
height = image.height
width = image.width
resolve({ height, width })
// clearTimeout(timer)
}
}
// }, 100)
});
}
// 获取文件列表
async function getFileList() {
if (loading.value) return;
loading.value = true;
try {
const res = await $http.file.getFileList({
keyword: kw.value,
page_num: pn.value,
page_size: ps.value,
});
// console.log('>>> --> getFileList --> res:', res);
if (pn.value === 1) {
fileList.value = res.data;
resetWaterfall();
} else {
// 追加新数据
res.data.forEach((item: any) => {
fileList.value.push(item);
addToWaterfall(item);
});
}
} catch (error) {
console.error('获取文件列表失败:', error);
} finally {
loading.value = false;
}
}
// // 获取我的文件列表
// async function getMyList() {
// if (loading.value) return;
// loading.value = true;
// try {
// const res = await $http.file.getMyList({
// page_num: pn.value,
// page_size: ps.value,
// });
// // console.log('>>> --> getFileList --> res:', res);
// if (pn.value === 1) {
// fileList.value = res.data;
// resetWaterfall();
// } else {
// // 追加新数据
// res.data.forEach((item: any) => {
// fileList.value.push(item);
// addToWaterfall(item);
// });
// }
// } catch (error) {
// console.error('获取文件列表失败:', error);
// } finally {
// loading.value = false;
// }
// }
// 监听滚动事件
const handleScroll: any = throttle((e: any) => {
console.log('>>> --> handleScroll --> loading:', e)
if (loading.value) return;
const scrollTop = e.target.scrollTop
console.log('>>> --> handleScroll --> scrollTop:', scrollTop)
const scrollHeight = e.target.scrollHeight
// console.log('>>> --> handleScroll --> scrollHeight:', scrollHeight)
const clientHeight = e.target.offsetHeight;
// 当滚动到距离底部20%时加载更多
// console.log('>>> --> clientHeight --> clientHeight:', clientHeight)
if (scrollTop + clientHeight >= scrollHeight * 0.8) {
console.log('>>> --> handleScroll --> 加载更多')
pn.value++;
getFileList();
}
}, 1000)
function onSearch() {
pn.value = 1;
getFileList();
}
function downloadFile(url: string) {
console.log('>>> --> downloadFile --> url:', url)
// 创建临时a标签
const link = document.createElement('a');
// 设置下载链接
link.href = url;
// 提取文件名
const fileName = url.split('/').pop() || 'downloaded-file';
// 设置下载属性和文件名
link.download = fileName;
// 设置为隐藏元素
link.style.display = 'none';
// 添加到文档
document.body.appendChild(link);
// 触发点击事件
link.click();
// 移除临时元素
document.body.removeChild(link);
}
onMounted(() => {
getFileList();
// 计算初始列数
calculateColumnCount();
// 添加窗口大小变化监听
window.addEventListener('resize', calculateColumnCount);
// 添加滚动监听
window.addEventListener('scroll', handleScroll);
});
onUnmounted(() => {
pn.value = 1;
kw.value = '';
fileList.value = [];
resetWaterfall();
// 移除监听
window.removeEventListener('resize', calculateColumnCount);
window.removeEventListener('scroll', handleScroll);
});
</script>
<style scoped lang="less">
/* 画廊页样式 */
:deep(.devui-tabs__nav) {
display: flex;
justify-content: center;
width: 100% !important;
// padding: 0 10%;
li {
width: 50%;
display: flex;
justify-content: center;
}
li a span {
font-size: 18px !important;
font-weight: 500;
}
}
.ps {
height: calc(100vh - 65px);
width: 100%;
}
:deep(.devui-upload) {
width: 100%;
&>div {
width: 100%;
}
}
</style>

View File

@ -1,44 +1,47 @@
<template>
<d-card class="mt-10 bg-[#ffffff60] rounded-[10px]" shadow="never">
<d-tabs v-model="tid" type="pills">
<d-tab id="tab1" title="登录">
<d-form ref="formLogin" layout="vertical" :data="loginData" :rules="rules">
<d-form-item field="username">
<d-input v-model="loginData.username" placeholder="请输入用户名" />
</d-form-item>
<d-form-item field="password">
<d-input v-model="loginData.password" show-password placeholder="请输入密码" />
</d-form-item>
<d-form-item class="form-operation-wrap">
<d-button class="w-full" variant="solid" @click="login"> </d-button>
</d-form-item>
</d-form>
</d-tab>
<d-tab id="tab2" title="注册">
<d-form ref="formReg" layout="vertical" :data="regData" :rules="rrules">
<d-form-item field="username">
<d-input v-model="regData.username" placeholder="请输入用户名" />
</d-form-item>
<d-form-item field="password">
<d-input v-model="regData.password" show-password placeholder="请输入用密码" />
</d-form-item>
<d-form-item field="nickname">
<d-input v-model="regData.nickname" placeholder="请输入昵称" />
</d-form-item>
<d-form-item class="form-operation-wrap">
<d-button class="w-full" variant="solid" @click="register">注册</d-button>
</d-form-item>
</d-form>
</d-tab>
</d-tabs>
</d-card>
<n-card class="mt-10 rounden-[10px] w-[500px]" shadow="never">
<n-tabs v-model:value="tid" justify-content="space-evenly" animated>
<n-tab-pane name="tab1" tab="登录">
<n-form ref="formLogin" layout="vertical" :data="loginData" :rules="rules">
<n-form-item field="username">
<n-input v-model:value="loginData.username" placeholder="请输入用户名" />
</n-form-item>
<n-form-item field="password">
<n-input v-model:value="loginData.password" type="password" show-password-on="click" placeholder="请输入密码" />
</n-form-item>
<n-form-item class="form-operation-wrap">
<n-button class="w-full" type="primary" @click="login"> </n-button>
</n-form-item>
</n-form>
</n-tab-pane>
<n-tab-pane name="tab2" tab="注册">
<n-form ref="formReg" layout="vertical" :data="regData" :rules="rrules">
<n-form-item field="username">
<n-input v-model:value="regData.username" placeholder="请输入用户名" />
</n-form-item>
<n-form-item field="password">
<n-input v-model:value="regData.password" type="password" show-password-on="click" placeholder="请输入用密码" />
</n-form-item>
<n-form-item field="nickname">
<n-input v-model:value="regData.nickname" placeholder="请输入昵称" />
</n-form-item>
<n-form-item class="form-operation-wrap">
<n-button class="w-full" type="primary" @click="register">注册</n-button>
</n-form-item>
</n-form>
</n-tab-pane>
</n-tabs>
</n-card>
</template>
<script setup lang="ts">
const router = useRouter()
const emit = defineEmits<{
(e: 'update:visible', value: boolean): void
}>()
const props = defineProps({
setVisible: {
type: Function,
default: () => { },
}
})
// 登录注册逻辑
const tid = ref("tab1");
const formLogin: any = ref(null);
@ -77,8 +80,8 @@ const rrules: any = reactive({
})
function login() {
console.log('>>> --> login --> formLogin.value:', usrLog.isLogin)
formLogin.value.validate(async (is: boolean, b: any) => {
if (!is) {
formLogin.value?.validate(async (is: boolean) => {
if (is) {
$msg.error('信息填写不正确,请检查后再提交')
} else {
const res = await $http.user.login(loginData)
@ -90,15 +93,14 @@ function login() {
$cookies.set('userinfo', res.data.userinfo, '1d')
$msg.success(res.msg)
usrLog.setIsLogin(true)
// router.push({ path: "/" })
emit("update:visible",false)
props.setVisible(false)
}
})
}
function register() {
formReg.value.validate(async (is: boolean, b: any) => {
if (!is) {
formReg.value.validate(async (is: boolean) => {
if (is) {
$msg.error('信息填写不正确,请检查后再提交')
} else {
const res = await $http.user.register(regData)
@ -108,8 +110,10 @@ function register() {
}
$msg.success(res.msg)
tid.value = 'tab1'
formReg.value.resetForm()
loginData.username = regData.username
regData.username = ''
regData.nickname = ''
regData.password = ''
}
})
}

View File

@ -1,14 +1,14 @@
<template>
<div class="pr-8">
<d-card shadow="never" class="mt-4 bg-white">
<n-card embedded class="mt-4 shadow">
<!-- <div class="dt-card mt-10 bg-white"> -->
<template #title>
<template #header>
<div class="flex items-center">
<icon-time class="w-5 mr-2"></icon-time>
时间日期
</div>
</template>
<template #content>
<template #default>
<div class="w-full pr-20 text-center text-[#ec66ab] font-500 text-4xl font-[yj]">{{ t }}</div>
<div class="mt-3 flex justify-between">
<span>今年已过了{{ jq.dayOfYear }}</span>
@ -18,19 +18,20 @@
<img v-else class="absolute top-0 right-4" width="120" src="@/assets/images/onwork.png" alt="">
</template>
<!-- </div> -->
</d-card>
</n-card>
<d-card shadow="never" class="mt-4 bg-white">
<template #title>
<n-card embedded class="mt-4 shadow">
<template #header>
<div class="flex items-center">
<icon-news class="w-5 mr-2"></icon-news>
百度新闻
</div>
</template>
<template #content>
<template #default>
<div class="py-1" v-for="i in bdNews" :key="i.id">
<a class="devui-link flex justify-between truncate" :href="i.url" target="_blank">
<!-- 淡蓝色 -->
<a class="text-[#526ecc] no-underline hover:text-primary hover:underline flex justify-between truncate" :href="i.url" target="_blank">
<span class="flex items-center">{{ i.index }}. {{ i.title }}
<icon-hot v-show="i.index < 4" class="ml-2 w-4 text-[red] inline-block"></icon-hot>
</span>
@ -39,7 +40,7 @@
</div>
<div class="mt-2 justify-between flex items-center">
<div class="w-2/5 h-px bg-[#ec66ab]"></div>
<a class="devui-link text-[#ec66ab] flex items-center" href="https://www.baidu.com/s?ie=utf-8&wd=百度新闻"
<a class="text-[#526ecc] no-underline text-[#ec66ab] flex items-center" href="https://www.baidu.com/s?ie=utf-8&wd=百度新闻"
target="_blank">
更多
<icon-right class="ml-1 w-4 text-primary inline-block"></icon-right>
@ -47,18 +48,18 @@
<div class="w-2/5 h-px bg-[#ec66ab]"></div>
</div>
</template>
</d-card>
</n-card>
<d-card shadow="never" class="mt-4 bg-white">
<template #title>
<n-card embedded class="mt-4 shadow">
<template #header>
<div class="flex items-center">
<icon-date class="w-5 mr-2"></icon-date>
农历节气
<div class="ml-12 text-[#ec66ab] font-500">{{ jq.yearTips }} {{ jq.lunarCalendar }}</div>
</div>
</template>
<template #content>
<template #default>
<div class="truncate text-sm mx-[5%]">
{{ jq.suit }}
</div>
@ -70,7 +71,7 @@
</div>
<div class="mt-2 text-center">{{ jq.solarTerms }}</div>
</template>
</d-card>
</n-card>
</div>
</template>
@ -132,8 +133,14 @@ onUnmounted(() => {
src: url('@/assets/font/LCDML.woff2');
}
:deep(.n-card > .n-card__content, .n-card > .n-card__footer){
padding: 8px 25px !important;
}
// .dt-card {
// background-image: url('@/assets/images/中秋节中国风边框34.png');
// background-size: 100% 100%;
// padding: 20px 40px;
// }</style>
// }
</style>

35
src/components/mask.vue Normal file
View File

@ -0,0 +1,35 @@
<template>
<Teleport to="body">
<div v-if="visible"
class="fixed top-0 left-0 z-[1000] w-[100vw] h-[100vh] flex items-center justify-center bg-[rgba(0,0,0,0.5)]">
<slot></slot>
<div @click.prevent="handdleClose" class="absolute w-8 h-8 top-4 right-4 rounded-full bg-white flex items-center justify-center text-[#ec66ab] cursor-pointer">X</div>
</div>
</Teleport>
</template>
<script setup lang="ts">
//mark import
//mark data
const props = defineProps({
visible: {
type: Boolean,
default: false,
},
setVisible: {
type: Function,
default: () => { },
}
});
//mark method
function handdleClose() {
props.setVisible(false)
}
//mark 周期、内置函数等
</script>
<style scoped lang="less"></style>

View File

@ -5,36 +5,15 @@
<img :src="logo" alt="柚子的网站" class="h-9 align-middle" />
</div>
<!-- 主导航菜单 -->
<d-menu mode="horizontal" router class="ml-5 h-14 text-[16px] " :default-select-keys="[key]">
<d-menu-item key="home">
<d-icon :component="homeSvg" class="w-5 mr-1"></d-icon>
首页
</d-menu-item>
<d-menu-item key="gallery">
<d-icon :component="picSvg" class="w-5 mr-1"></d-icon>
画廊
</d-menu-item>
<d-menu-item key="article">
<d-icon :component="artiSvg" class="w-5 mr-1 "></d-icon>
文章
</d-menu-item>
<d-menu-item key="widget">
<d-icon :component="settingSvg" class="w-5 mr-1 "></d-icon>
工具
</d-menu-item>
<d-menu-item key="appshare">
<d-icon :component="downSvg" class="w-5 mr-1 "></d-icon>
软件分享
</d-menu-item>
<d-menu-item key="plink">
<d-icon :component="linkSvg" class="w-5 mr-1 "></d-icon>
友链
</d-menu-item>
</d-menu>
<div>
<n-menu :icon-size="12" v-model:value="activeKey" class="" mode="horizontal" :options="menuOptions" />
</div>
<!-- 用户区域 -->
<div class="!text-[#ec66ab] flex items-center" @click="gotoHf">
<span class="flex items-center location-info truncate">
<d-icon color="#ec66ab" class="mr-1" name="location-new"></d-icon>
<n-icon class="mr-1">
<icon-loc class="w-[26px] h-[26px]"></icon-loc>
</n-icon>
{{ locationInfo }}
</span>
<span class="mx-3 text-gray-300">|</span>
@ -44,47 +23,35 @@
</div>
<div class="flex items-center mr-8">
<d-dropdown class="cursor-pointer w-[100px]" v-if="userinfo" trigger="hover">
<n-dropdown class="cursor-pointer w-[100px]" v-if="userinfo" :options="oprOp" @select="handleSelect"
trigger="hover">
<div class="flex items-center">
<d-avatar :img-src="userinfo.ava_url" class="cursor-pointer" alt="用户的头" />
<n-avatar round :src="userinfo.ava_url" class="cursor-pointer" alt="用户的头" />
<div class="cursor-pointer ml-2 text-gray text-sm">{{ userinfo.nickname }}</div>
</div>
<template #menu>
<ul class="list-menu">
<!-- hover为淡粉色 -->
<li class="w-full p-2 text-center hover:text-primary hover:bg-[#f5f0f0] cursor-pointer" @click="logout">
登出
</li>
<li class="w-full p-2 text-center hover:text-primary hover:bg-[#f5f0f0] cursor-pointer" @click="">
控制台
</li>
<li class="w-full p-2 text-center hover:text-primary hover:bg-[#f5f0f0] cursor-pointer" @click="">
设置
</li>
</ul>
</template>
</d-dropdown>
<div v-else class="flex items-center">
<d-avatar class="cursor-pointer" @click="toLogin"></d-avatar>
<div class="cursor-pointer ml-2 text-gray text-sm" @click="toLogin">登录</div>
</n-dropdown>
<div v-else class="flex items-center" @click="toLogin">
<n-avatar round class="cursor-pointer"></n-avatar>
<div class="cursor-pointer ml-2 text-gray text-sm" >登录</div>
</div>
</div>
<!-- 登录弹窗 -->
<d-modal class="!w-120" v-model="visible">
<login-modal v-model:visible="visible"></login-modal>
</d-modal>
<masked :visible="visible" :setVisible="setVisible">
<loginModal :setVisible="setVisible" />
</masked>
</div>
<div class="flex justify-between bg-white lg:hidden">
<div class="pl-2 items-centerflex" slot="brand" @click="">
<img :src="logo" alt="柚子的网站" class="h-9 align-middle" />
</div>
<div class="flex items-center mr-2">
<div v-if="userinfo" class="flex items-center">
<d-avatar :img-src="userinfo.ava_url" class="cursor-pointer" alt="用户的头" />
<div class="cursor-pointer ml-2 text-gray text-sm">{{ userinfo.nickname }}</div>
</div>
<div v-if="userinfo" class="flex items-center">
<n-avatar :src="userinfo.ava_url" round class="cursor-pointer" alt="用户的头" />
<div class="cursor-pointer ml-2 text-gray text-sm">{{ userinfo.nickname }}</div>
</div>
<div v-else class="flex items-center">
<d-avatar class="cursor-pointer" @click="toLogin"></d-avatar>
<n-avatar round class="cursor-pointer" @click="toLogin"></n-avatar>
<div class="cursor-pointer ml-2 text-gray text-sm" @click="toLogin">登录</div>
</div>
</div>
@ -101,16 +68,16 @@ import linkSvg from '@/icon/menu/link.svg';
import picSvg from '@/icon/menu/pic.svg';
import settingSvg from '@/icon/menu/setting.svg';
import loginModal from '@/components/Login.vue'
import masked from '@/components/mask.vue'
import { onMounted, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { useRoute, useRouter, RouterLink } from 'vue-router';
const activeKey = ref('home')
const route = useRoute();
const visible = ref(false);
const router = useRouter();
const key = ref("home");
const locationInfo = ref("获取位置中...");
const latitude = ref<number | null>(null);
const longitude = ref<number | null>(null);
@ -122,7 +89,69 @@ const userinfo: any = ref(null)
const nav: any = useTemplateRef('nav')
const navx = $store.nav.useNavStore()
const usrLog = $store.log.useLogStore()
console.log('>>> --> route:', route)
const menuOptions = ref([
{
label: () => h(RouterLink, { to: '/home', class: 'flex items-center justify-center' }, { default: () => '首页' }),
key: "home",
icon: () => h(homeSvg)
},
{
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: () => '文章管理' }),
key: "blog",
icon: () => h(artiSvg)
},
{
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: () => '软件管理' }),
key: "apps",
icon: () => h(settingSvg)
},
{
label: () => h(RouterLink, { to: '/plink', class: 'flex items-center justify-center' }, { default: () => '友链管理' }),
key: "plink",
icon: () => h(linkSvg)
},
]);
const oprOp = ref([
{
key: 'logout',
label: '退出登录',
},
{
key: 'console',
label: '控制台',
},
{
key: 'setting',
label: '设置',
}
])
function setVisible(v: any) {
visible.value = v
}
function handleSelect(key: string) {
console.log('>>> --> handleSelect --> key:', key)
if (key == 'logout') {
logout()
return
}
if (key == 'console') {
router.push('/console')
return
}
}
// 获取地理位置
const getLocation = () => {
if (!navigator.geolocation) {
@ -198,7 +227,7 @@ async function handdleJw(jw: string) {
}
watch(() => route.name, (newVal) => {
key.value = newVal as string
activeKey.value = newVal as string
})
function goHome() {
@ -220,6 +249,9 @@ function logout() {
usrLog.setIsLogin(false)
userinfo.value = null;
}
function gotoConsole() {
window.open("https://www.hxyouzi.com/console/home", "_BLACK")
}
function gotoHf() {
console.log('>>> --> gotoHf --> fxlink:', fxlink)
@ -230,7 +262,10 @@ onMounted(() => {
userinfo.value = $cookies.get('userinfo');
console.log('>>>>>>>>>>', userinfo.value);
key.value = route.name as string;
setTimeout(() => {
console.log('>>>>>>>>>>', route)
activeKey.value = route.name as string;
}, 20);
console.log('>>> --> route.name:', route.name)
getLocation(); // 组件挂载时获取位置
@ -242,7 +277,7 @@ onMounted(() => {
});
onBeforeUpdate(() => {
userinfo.value = $cookies.get('userinfo');
key.value = route.name as string;
activeKey.value = route.name as string;
const h: number = nav.value.clientHeight
// console.log('******>>> --> nav.value:', nav.value)
// console.log('()()()()()>>> --> h:', h)
@ -257,32 +292,10 @@ onBeforeUpdate(() => {
margin-bottom: 1px;
}
:deep(.devui-menu-horizontal .devui-menu-item:hover span .icon) {
color: var(--devui-brand, #5e7ce0) !important;
fill: var(--devui-brand, #5e7ce0) !important;
:deep(.n-menu-item-content__icon) {
width: 16px !important;
height: 16px !important;
}
:deep(.devui-menu-item-select span svg) {
color: var(--devui-brand, #5e7ce0) !important;
fill: var(--devui-brand, #5e7ce0) !important;
line-height: 100% !important;
}
:deep(.devui-menu-item-select span) {
color: var(--devui-brand, #5e7ce0) !important;
}
:deep(.devui-menu-horizontal) {
padding: 14px 20px 6px;
}
:deep(.devui-menu-item span) {
display: flex;
align-items: center;
.devui-icon__container {
display: flex;
align-items: center;
}
}
</style>