wordpress网站统计插件下载,英文网站常用字体,wordpress 折叠内容,泰安网站建设公司哪家好文章目录 设置主题样式变量封装公共布局组件封装 Logo 组件封装 Menu 菜单组件封装 Breadcrumb 面包屑组件封装 TabBar 标签栏组件封装 Main 内容区组件封装 Footer 底部组件封装 Theme 主题组件 经典布局水平布局响应式布局搭建 Layout 布局组件添加 Layout 路由配置启动项目 … 文章目录 设置主题样式变量封装公共布局组件封装 Logo 组件封装 Menu 菜单组件封装 Breadcrumb 面包屑组件封装 TabBar 标签栏组件封装 Main 内容区组件封装 Footer 底部组件封装 Theme 主题组件 经典布局水平布局响应式布局搭建 Layout 布局组件添加 Layout 路由配置启动项目 设置主题样式变量 创建主题变量文件src/assets/styles/theme.scss 添加页面布局组件用到的变量 :root {--os-layout-aside-width: 224px; // 侧边栏宽度--os-layout-logo-height: 56px; // 头部高度--os-layout-header-height: 56px; // 头部高度--os-layout-header-menu-width: 300px; // 头部菜单宽度--os-layout-footer-height: 40px; // 底部高度--os-layout-tab-height: 40px; // 底部高度
}设置全局滚动条样式 /* scroll bar */
::-webkit-scrollbar {width: 6px;height: 6px;
}::-webkit-scrollbar-thumb {background-color: var(--el-border-color-darker);border-radius: 20px;
}在统一管理和维护项目的样式文件src/assets/styles/index.scss中导入主题样式文件 import theme.scss;注统一管理和维护项目的样式文件src/assets/styles/index.scss需在mian.ts中导入注意导入顺序。
封装公共布局组件
封装 Logo 组件 创建 Logo 组件src/layouts/components/Logo/index.vue 通过import.meta.env获取.env文件中定义的环境变量环境变量使用详情跳转认识和使用 Vite 环境变量配置 script setup langts
const app_title import.meta.env.VITE_APP_TITLE
/scriptLogo 组件内容添加 Logo 图标和项目标题 template!-- logo 容器 --div classlogo-container!-- logo 图标 --svg-icon width32px height32px namelogo /!-- 应用标题只在中等及以上屏幕尺寸上可见 --span classlogo-title hidden md:block{{ app_title }}/span/div
/template添加样式 style scoped langpostcss
.logo-container {apply flex items-center justify-center;height: var(--os-layout-logo-height);width: var(--os-layout-aside-width);.logo-title {apply text-lg font-bold subpixel-antialiased;apply bg-clip-text text-transparent bg-gradient-to-r from-pink-500 to-violet-500;}
}
/style封装 Menu 菜单组件 创建 Menu 菜单组件src/layouts/components/Menu/index.vue 在 el-menu 组件中使用 props 来控制 mode 属性可以实现菜单的不同显示模式如 vertical 或 horizontal script setup langts
const props defineProps{mode?: vertical | horizontal
}()
/script使用 ElementPlus 的 el-menu 菜单组件搭建垂直菜单 template!-- 菜单容器 --div classmenu-container!-- Element UI 菜单组件 --el-menuclassos-menu:modeprops.mode!-- 一级菜单 --el-sub-menu index1!-- 一级菜单标题 --template #titlespanNavigator One/span/template!-- 二级菜单 --el-menu-item index1-1item one/el-menu-itemel-menu-item index1-2item two/el-menu-item/el-sub-menu!-- 一级菜单 --el-menu-item index2spanNavigator Two/span/el-menu-item/el-menu/div
/template添加样式 style scoped langpostcss
.menu-container{background-color: var(--el-menu-bg-color);.os-menu{apply border-0;.el-menu--horizontal{height: calc(var(--os-layout-logo-height) - 1px);}}
}
/style封装 Breadcrumb 面包屑组件 创建 src/layouts/components/Breadcrumb/index.vue 使用 ElementPlus el-breadcrumb 面包屑组件 templateel-breadcrumb separator/ classbreadcrumb-containerel-breadcrumb-item :to{ path: / }homepage/el-breadcrumb-itemel-breadcrumb-itemmanagement/el-breadcrumb-itemel-breadcrumb-itemlist/el-breadcrumb-itemel-breadcrumb-itemdetail/el-breadcrumb-item/el-breadcrumb
/template添加样式 style scoped langpostcss
.breadcrumb-container {display: flex;flex-wrap: nowrap; /* 防止换行 */overflow: hidden; /* 横向滚动溢出处理 */padding-right: 12px;
}
/style封装 TabBar 标签栏组件 创建 src/layouts/components/TabBar/index.vue 生成 TabBar 标签数据 script setup langts
const tabs Array(1).fill({label: About,name: about,icon: About,path: /about
})
/script使用 ElementPlus el-tabs 标签组件Scrollbar 组件替换浏览器原生滚动条 template!-- Tab Bar --div classtab-bar-containerdiv classtab-bar-boxel-scrollbarel-tabstab-positiontoptypecardclosableel-tab-panev-for(item, index) in tabs:keyindex:nameitem.nametemplate #labelspan classtab-titlesvg-icon :nameitem.icon /span{{ item.label }}/span/span/template/el-tab-pane/el-tabs/el-scrollbar/divdiv classmore-buttonel-dropdown triggerclickspansvg-icon nameMore //spantemplate #dropdownel-dropdown-menuel-dropdown-item关闭/el-dropdown-item/el-dropdown-menu/template/el-dropdown/div/div
/template添加样式 style scoped langscss
.tab-bar-container {display: flex;align-items: center;gap: 8px;border-bottom: 1px solid var(--el-border-color-light);.tab-bar-box {display: flex;flex-grow: 1;margin-left: 8px;width: calc(100% - 60px);.tab-title{display: flex;align-items: center;gap: 8px;}}.more-button {display: flex;align-items: center;justify-content: center;width: var(--os-layout-tab-height);height: var(--os-layout-tab-height);border-left: 1px solid var(--el-border-color-light);}
}:deep(.el-tabs) {.el-tabs__header {height: var(--os-layout-tab-height);padding: 0;margin: 0;border-bottom: none;.el-tabs__nav-wrap {.el-tabs__nav-scroll {.el-tabs__nav {border: none;.el-tabs__item {height: calc(var(--os-layout-tab-height) - 2px);line-height: calc(var(--os-layout-tab-height) - 2px);border: none;position: relative; // 确保父元素是相对定位的::before {content: ;position: absolute;bottom: 0;width: 100%;height: 2px;background-color: transparent;}.is-active {color: var(--el-color-primary);fill: var(--el-color-primary);::before {background-color: var(--el-color-primary); // 改变背景色以显示下划线}}}}}}}
}
/style封装 Main 内容区组件 创建 src/layouts/components/Main/index.vue script setup langts/scripttemplatedivMain/div
/templatestyle scoped langscss/style后续补充内容…
封装 Footer 底部组件 创建 src/layouts/components/Footer/index.vue 通过import.meta.env获取.env文件中定义的环境变量 script setup langts
const app_title import.meta.env.VITE_APP_TITLE
/script添加内容 templatediv classfooter-container!-- 左侧公司名称或标志 --div classflex-contentsvg-icon namelogo /span classlogo-title{{ app_title }}/span/div!-- 中间导航链接 --div classflex-contenta hrefabout关于我们/aa href#contact联系我们/aa href#privacy-policy隐私政策/aa href#terms-of-service服务条款/a/div!-- 右侧版权信息 --div classtext-rightcopy; 2024 Octopus. 保留所有权利./div/div
/template添加样式 style scoped langpostcss
.footer-container{apply flex items-center w-full;apply select-none text-xs;height: var(--os-layout-footer-height);apply justify-center lg:justify-between;.flex-content{apply items-center gap-2;apply flex justify-center gap-1 text-gray-400;apply hidden lg:flex;.logo-title {apply font-bold subpixel-antialiased text-sm;apply bg-clip-text text-transparent bg-gradient-to-r from-pink-500 to-violet-500;}}
}
/style封装 Theme 主题组件 创建 src/stores/modules/theme/types.ts 定义主题类型 export type LayoutMode classic | horizontal | responsive
// 主题配置
export interface ThemeConfig {showThemeConfig: boolean,darkThemeEnabled: boolean,grayThemeEnabled: boolean,layoutMode: LayoutMode,themePrimaryColor: string,predefineColors: string[]
}创建 src/stores/modules/theme/index.ts 仓库存储主题状态 import { defineStore } from pinia
import { reactive, watch } from vue
import { ThemeConfig } from ./types
import { ElMessage } from element-plus
import { getDarkColor, getLightColor } from /utils/Color// theme store
export const useThemeStore defineStore(theme,() {const themeConfig reactiveThemeConfig({showThemeConfig: false,darkThemeEnabled: false,grayThemeEnabled: false,layoutMode: classic,themePrimaryColor: #409eff,predefineColors: [#409eff]})// 切换显示状态的方法const toggleThemeConfig () {themeConfig.showThemeConfig !themeConfig.showThemeConfig}// 黑暗主题切换watch(() themeConfig.darkThemeEnabled, () {const html document.documentElement as HTMLElementif (themeConfig.darkThemeEnabled) {html.setAttribute(class, dark)} else {html.removeAttribute(class)}changeThemeColor(themeConfig.themePrimaryColor)})watch(() themeConfig.grayThemeEnabled,() {if (themeConfig.grayThemeEnabled) {document.documentElement.dataset.theme gray} else {document.documentElement.dataset.theme }})// 添加预定义颜色function addPredefineColor(color:string) {console.log(color, color)const predefineColors themeConfig.predefineColors// 查找元素的索引const index predefineColors.indexOf(color)if (index ! -1) {// 使用 splice 方法删除该元素predefineColors.splice(index, 1)}if (themeConfig.predefineColors.length 10) {themeConfig.predefineColors.pop() // 删除队列中的第一个元素}themeConfig.predefineColors.unshift(color)}// 修改主题颜色const changeThemeColor (color:string ) {if (!color) {color #409effElMessage({ type: success, message: 主题颜色已重置 })}addPredefineColor(color)// 计算主题颜色变化document.documentElement.style.setProperty(--el-color-primary, color)document.documentElement.style.setProperty(--el-color-primary-dark-2,themeConfig.darkThemeEnabled ? ${getLightColor(color, 0.2)} : ${getDarkColor(color, 0.3)})for (let i 1; i 9; i) {const primaryColor themeConfig.darkThemeEnabled ? ${getDarkColor(color, i / 10)} : ${getLightColor(color, i / 10)}document.documentElement.style.setProperty(--el-color-primary-light-${i}, primaryColor)}}return {themeConfig,toggleThemeConfig,changeThemeColor}},{persist: true})创建 src/layouts/components/Theme/index.vue 主题组件并引入主题仓库 script setup langts
import { useThemeStore } from /stores/modules/theme
import { onMounted } from vueconst { themeConfig, changeThemeColor } useThemeStore()onMounted(() {// 在组件挂载到 DOM 后更新主题颜色changeThemeColor(themeConfig.themePrimaryColor)
})
/script使用 el-drawer 抽屉组件进行主题布局 templatedivel-drawer v-modelthemeConfig.showThemeConfig size300template #header{ titleId }span :idtitleId classtheme-header 主题配置 /span/templateel-scrollbardiv classmr-4el-divider布局样式/el-dividerdiv classlayout-boxel-tooltip effectdark content经典布局 placementtop :show-after200div:class[layout-item layout-classic, { is-active: themeConfig.layoutMode classic }]clickthemeConfig.layoutModeclassicdiv classlayout-dark/divdiv classlayout-containerdiv classlayout-light/divdiv classlayout-content/div/divsvg-icon classselect-layout nameAbout v-ifthemeConfig.layoutMode classic //div/el-tooltipel-tooltipeffectdarkcontent横向布局placementtop:show-after200div:class[layout-item layout-transverse, { is-active: themeConfig.layoutMode horizontal }]clickthemeConfig.layoutModehorizontaldiv classlayout-dark/divdiv classlayout-content/divsvg-icon classselect-layout nameAbout v-if themeConfig.layoutMode horizontal //div/el-tooltip/divel-divider主题风格/el-dividerdiv classswitch-containerdiv classswitch-boxdiv classswitch-titlespan主题颜色/spanel-tooltip content主题颜色 placementtopsvg-icon classsize-4 nameAbout/svg-icon/el-tooltip/divel-color-pickercolor-formathexv-modelthemeConfig.themePrimaryColor:predefinethemeConfig.predefineColorschangechangeThemeColor//divdiv classswitch-boxdiv classswitch-titlespan暗黑主题/spanel-tooltip content暗黑主题 placementtopsvg-icon classsize-4 nameAbout/svg-icon/el-tooltip/divel-switch v-modelthemeConfig.darkThemeEnabled //divdiv classswitch-boxdiv classswitch-titlespan灰色模式/spanel-tooltip content灰色模式 placementtopsvg-icon classsize-4 nameAbout/svg-icon/el-tooltip/divel-switch v-modelthemeConfig.grayThemeEnabled //div/divel-divider界面设置/el-dividerdiv classswitch-containerdiv classswitch-boxdiv classswitch-titlespantheme/span/divel-switch inline-prompt //div/div/div/el-scrollbar/el-drawer/div
/template为组件添加样式 style scoped langpostcss
.theme-header {apply text-base font-bold flex items-center;
}.switch-container {apply flex-grow space-y-2;
}.switch-box {apply flex justify-between items-center w-full;
}.switch-title {apply flex gap-2 items-center;
}:deep(.el-drawer__header) {apply px-5 py-0 h-12 border-b-2 border-solid m-0;color: var(--el-text-color-regular);border-color: var(--el-border-color-light);
}:deep(.el-drawer__title) {font-size: 20px;
}:deep(.el-drawer__body) {apply py-0 pr-0;
}.layout-box {position: relative;display: flex;flex-wrap: wrap;justify-content: space-between;padding: 15px 15px 0;.layout-item {position: relative;box-sizing: border-box;width: 100px;height: 70px;padding: 6px;cursor: pointer;border-radius: 5px;box-shadow: 0 0 5px 1px var(--el-border-color-dark);transition: all 0.2s;.layout-dark {background-color: var(--el-color-primary);border-radius: 3px;}.layout-light {background-color: var(--el-color-primary-light-5);border-radius: 3px;}.layout-content {background-color: var(--el-color-primary-light-8);border: 1px dashed var(--el-color-primary);border-radius: 3px;}.select-layout {position: absolute;right: 10px;bottom: 10px;fill: var(--el-color-primary);transition: all 0.2s;}:hover {box-shadow: 0 0 5px 1px var(--el-text-color-secondary);}}.is-active {box-shadow: 0 0 0 2px var(--el-color-primary) !important;}.layout-classic {display: flex;justify-content: space-between;margin-bottom: 20px;.layout-dark {width: 20%;}.layout-container {display: flex;flex-direction: column;justify-content: space-between;width: 72%;.layout-light {height: 20%;}.layout-content {height: 67%;}}}.layout-transverse {display: flex;flex-direction: column;justify-content: space-between;margin-bottom: 15px;.layout-dark {height: 20%;}.layout-content {height: 67%;}}
}
/style经典布局 创建经典页面布局组件src/layouts/LayoutClassic/index.vue 导入布局组件 script setup langts
import Footer from /layouts/components/Footer/index.vue; // 引入页脚组件
import Menu from /layouts/components/Menu/index.vue; // 引入菜单组件
import Logo from /layouts/components/Logo/index.vue; // 引入Logo组件
import Main from /layouts/components/Main/index.vue; // 引入主要内容组件
import TabBar from /layouts/components/TabBar/index.vue; // 引入标签栏组件
import Breadcrumb from /layouts/components/Breadcrumb/index.vue; // 引入面包屑导航组件import { useThemeStore } from /stores/modules/theme // 引入主题仓库
const { toggleThemeConfig } useThemeStore()使用 ElementPlus 提供的 Container 布局容器快速搭建页面的基本结构 在组件中使用布局组件划分出页面结构侧边菜单栏、顶部、Tab 标签栏、主体和底部 el-container外层容器。 当子元素中包含 el-header 或 el-footer 时全部子元素会垂直上下排列 否则会水平左右排列。 el-header顶栏容器。 el-aside侧边栏容器。 el-main主要区域容器。 el-footer底栏容器。 templatediv classlayout-containerel-container!-- 左侧边栏 --el-aside!-- Logo 组件 --Logo classos-logo/!-- 菜单组件 --Menu classmenu-classic //el-asideel-container!-- 页面顶部区域 --el-header!-- 头部内容区域 --div classheader-content!-- 折叠按钮 --svg-icon classfold-expand-button nameFold /!-- 面包屑导航 --Breadcrumb //div!-- 头部菜单区域 --div classheader-menu!-- 语言切换下拉菜单 --el-dropdown :hide-on-clickfalsesvg-icon nameEarth /template #dropdownel-dropdown-menuel-dropdown-item简体中文/el-dropdown-item/el-dropdown-menu/template/el-dropdown!-- 搜索按钮 --svg-icon classcursor-pointer nameSearch /!-- 主题配置按钮 --el-tooltip content主题配置 placementbottomsvg-icon classcursor-pointer nameTheme clicktoggleThemeConfig //el-tooltip!-- 锁屏按钮 --el-tooltip content锁屏 placementbottomsvg-icon classcursor-pointer nameLock //el-tooltip!-- 全屏按钮 --el-tooltip content全屏 placementbottomsvg-icon classcursor-pointer nameFullScreen //el-tooltip!-- 用户信息下拉菜单 --el-dropdowndiv classflex items-center gap-1el-tag typeprimaryAdmin/el-tagel-avatar srchttps://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png //divtemplate #dropdownel-dropdown-menuel-dropdown-item commandprofiletemplate #defaultdiv classflex items-center gap-1svg-icon nameUser /span个人中心/span/div/template/el-dropdown-itemel-dropdown-item commandlogouttemplate #defaultdiv classflex items-center gap-1svg-icon nameLogout /span退出登录/span/div/template/el-dropdown-item/el-dropdown-menu/template/el-dropdown/div/el-header!-- 标签栏 --tab-bar classtab-container /!-- 主内容区域 --el-mainMain //el-main!-- 底部页脚 --el-footerFooter //el-footer/el-container/el-container/div
/template为组件添加样式 style scoped langpostcss
.layout-container {apply w-screen h-screen;.el-aside {apply h-full;apply border-r border-solid overflow-hidden;border-color: var(--el-border-color-light);width: var(--os-layout-aside-width);.os-logo {apply overflow-hidden pl-2;}.menu-classic {height: calc(100vh - var(--os-layout-logo-height));}}.el-container {apply h-full w-full;.tab-container {height: var(--os-layout-tab-height);}.el-header {apply flex items-center justify-between;apply border-b border-solid overflow-hidden;border-color: var(--el-border-color-light);height: var(--os-layout-header-height);.header-content {apply flex items-center gap-5;.fold-expand-button {apply cursor-pointer;apply size-6;}}.header-menu {apply flex items-center justify-between gap-3;}}.el-main {apply h-full p-3;background-color: var(--el-bg-color-page);}.el-footer {height: var(--os-layout-footer-height);}}
}
/style水平布局 创建经典页面布局组件src/layouts/LayoutClassic/index.vue 导入布局组件 script setup langts
import Footer from /layouts/components/Footer/index.vue; // 引入页脚组件
import Menu from /layouts/components/Menu/index.vue; // 引入菜单组件
import Logo from /layouts/components/Logo/index.vue; // 引入Logo组件
import Main from /layouts/components/Main/index.vue; // 引入主要内容组件
import TabBar from /layouts/components/TabBar/index.vue; // 引入标签栏组件import { useThemeStore } from /stores/modules/theme // 引入主题仓库
const { toggleThemeConfig } useThemeStore()
/script在组件中使用 Element UI 的布局组件划分出页面结构顶部、Tab 标签栏、主体和底部 templatediv classlayout-containerel-containerel-containerel-headerdiv classflexLogo classos-logo /Menu modehorizontal classmenu-horizontal //divdiv classheader-menu!-- 语言转换 --el-dropdown :hide-on-clickfalsesvg-icon nameEarth /template #dropdownel-dropdown-menuel-dropdown-item简体中文/el-dropdown-item/el-dropdown-menu/template/el-dropdown!-- 搜索按钮 --svg-icon classcursor-pointer nameSearch /!-- 皮肤按钮 --el-tooltip content主题配置 placementbottomsvg-icon classcursor-pointer nameTheme clicktoggleThemeConfig//el-tooltip!-- 锁屏按钮 --el-tooltip content锁屏 placementbottomsvg-icon classcursor-pointer nameLock //el-tooltip!-- 全屏按钮 --el-tooltip content全屏 placementbottomsvg-icon classcursor-pointer nameFullScreen //el-tooltip!-- 用户信息 --el-dropdowndiv classflex items-center gap-1el-tag typeprimaryAdmin/el-tagel-avatar srchttps://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png //divtemplate #dropdownel-dropdown-menuel-dropdown-item commandprofiletemplate #defaultdiv classflex items-center gap-1svg-icon nameUser /span个人中心/span/div/template/el-dropdown-itemel-dropdown-item commandlogouttemplate #defaultdiv classflex items-center gap-1svg-icon nameLogout /span退出登录/span/div/template/el-dropdown-item/el-dropdown-menu/template/el-dropdown/div/el-headertab-bar classtab-container /el-mainMain //el-mainel-footerFooter //el-footer/el-container/el-container/div
/template添加样式 style scoped langpostcss
.layout-container {apply w-screen h-screen;.el-aside {apply bg-amber-300 h-full;width: var(--os-layout-aside-width);}.el-container {apply h-full w-full;.tab-container {height: var(--os-layout-tab-height);}.el-header {apply w-full pl-2 pr-2 flex justify-between;height: var(--os-layout-header-height);apply border-b border-solid overflow-hidden;border-color: var(--el-border-color-light);.menu-horizontal{width: calc(100vw - var(--os-layout-aside-width) - var(--os-layout-header-menu-width));}.header-menu{apply flex items-center justify-between gap-3;}}.el-main {apply h-full p-3;background-color:var(--el-bg-color-page);}.el-footer {height: var(--os-layout-footer-height);}}
}
/style响应式布局 创建src/layouts/LayoutResponsive/index.vue响应式布局组件 添加公共组件 script setup langts
import Logo from /layouts/components/Logo/index.vue
import Main from /layouts/components/Main/index.vue
import Menu from /layouts/components/Menu/index.vue
import { ref } from vueimport { useThemeStore } from /stores/modules/theme
const { themeConfig } useThemeStore()const navDrawer ref(false)
const menuDrawer ref(false)
const translateShow ref(false)
/script页面布局 templatediv classlayout-responsiveel-containerel-header classflex items-center justify-betweendiv classh-full flex items-center gap-2svg-icon width30px height30px namemenu clickmenuDrawer !menuDrawer /Logo //divdiv classheader-menu!-- 搜索按钮 --svg-icon width28px height28px classcursor-pointer nameSearch /!-- 用户信息 --el-avatar srchttps://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.pngclicknavDrawer !navDrawer /!-- 导航信息 -- el-drawer v-modelnavDrawer size100%template #headerLogo //templatediv classnav-container a href#个人中心/ael-divider /divspan classflex items-center justify-between clicktranslateShow !translateShow翻译svg-icon nameEarth/svg-icon/span!-- 语言列表 --transition namefadediv v-showtranslateShow idlanguage-list classlanguage-list mt-2ulli classp-2英语/lili classp-2中文/lili classp-2西班牙语/li/ul/div/transition/divel-divider /div classnav-theme-switchspan暗黑主题/spanel-switch v-modelthemeConfig.darkThemeEnabled sizelarge //divel-divider /span退出登录/span/div/el-drawer/div/el-headerel-mainel-backtop target.el-main /Main //el-main/el-container!-- 菜单组件 --el-drawerv-modelmenuDrawerdirectionltrsize320pxMenu //el-drawer/div
/template添加样式 style scoped langpostcss
.layout-responsive {apply w-screen h-screen;.el-container {apply h-full w-full;.el-header {apply w-full flex pl-2;height: var(--os-layout-header-height);apply border-b border-solid overflow-hidden;border-color: var(--el-border-color-light);.header-menu {apply flex items-center justify-between gap-3;}}.tab-container {background-color: var(--el-bg-color);}.el-main {apply h-full;background-color: var(--el-bg-color-page);}}
}:deep(.el-drawer__header) {apply px-3 py-0 h-14 border-solid m-2;color: var(--el-text-color-regular);border-color: var(--el-border-color-light);
}:deep(.el-drawer__title) {font-size: 20px;
}:deep(.el-drawer__body) {apply py-0 px-8;
}:deep(.el-drawer__close-btn) {apply text-3xl;
}.nav-container {margin: 0 auto;padding: 24px 0 96px;max-width: 18rem;
}.nav-theme-switch {apply flex items-center justify-between rounded-md;
}/* 添加动画效果 */
.fade-enter-active {transition: opacity 0.5s ease;
}.fade-leave-active {transition: opacity 0.2s ease;
}.fade-enter-from, .fade-leave-to {opacity: 0;
}.logo-title {apply text-lg font-bold subpixel-antialiased;apply bg-clip-text text-transparent bg-gradient-to-r from-pink-500 to-violet-500;
}
/style搭建 Layout 布局组件 创建 Layout 布局组件 src/layouts/index.vue 导入经典布局组件 LayoutClassic 和水平布局组件 LayoutHorizontal创建一个 layoutMode 对象来将布局模式字符串映射到相应的组件使用 computed 函数根据 mode 动态选择布局模式。 script setup langts
import { type Component, computed, onMounted, onUnmounted, ref, watch } from vue
import LayoutClassic from /layouts/LayoutClassic/index.vue
import LayoutHorizontal from /layouts/LayoutHorizontal/index.vue
import LayoutResponsive from /layouts/LayoutResponsive/index.vue
import Theme from /layouts/components/Theme/index.vueimport { useThemeStore } from /stores/modules/theme
const { themeConfig } useThemeStore()// 定义布局模式与对应的组件类型
const layoutMode: Recordstring, Component {classic: LayoutClassic, // 经典布局horizontal: LayoutHorizontal, // 横向布局responsive: LayoutResponsive // 响应式布局
}// 布局模式
const layMode ref(themeConfig.layoutMode)// 监听主题配置模式
watch(() themeConfig.layoutMode, (newMode) {layMode.value newMode
})// 计算属性根据具体逻辑返回所选布局的组件
const mode computed(() layoutMode[layMode.value])// 响应式布局切换布局模式
const updateMode () {if (window.innerWidth 768) {layMode.value responsive} else {layMode.value themeConfig.layoutMode}
}onMounted(() {// 初始更新updateMode()window.addEventListener(resize, updateMode)
})onUnmounted(() {window.removeEventListener(resize, updateMode)
})
/scripttemplate!-- 根据 mode 的值渲染不同的布局样式 --component :ismode /Theme /
/templatestyle scoped langpostcss
/style添加 Layout 路由配置 在 src/App.vue 中添加代码当访问路由路径时Vue Router 会根据路由配置将对应的组件渲染到 router-view 中实现单页应用的页面切换效果 templaterouter-view /
/template在 src/router/index.ts 中添加路由 const router createRouter({routes: [{path: /,name: layout,component: () import(/layouts/index.vue)}]
})启动项目 终端执行命令启动项目 pnpm run dev浏览器访问http://localhost:8080/默认为经典布局样式 在 src/layouts/index.vue 中切换为水平布局样式查看页面 const mode computed(() layoutMode[horizontal])