文章目錄
- 1 CommonAside組件(靜態搭建)
- 1.1 Menu菜單
- 1.2 準備菜單數據
- 1.3 循環渲染菜單
- 1.3.1 el-menu結構
- 1.3.2 動態渲染圖標
- 1.4 樣式設計
- 1.5 整體代碼(CommonAside.vue)
- 2 CommonHeader組件(靜態搭建)
- 2.1 準備圖片URL數據
- 2.2 頁面布局
- 2.3 樣式設計
- 2.4 整體代碼(CommonHeader.vue)
- 3 附錄
- 3.1 列表filter
- 3.2 參考附錄
左側菜單欄:el-menu構建菜單,通過component渲染圖標。頭部導航欄:左側是一個圖標,中間是面包屑,右側是dropdown。
1 CommonAside組件(靜態搭建)
1.1 Menu菜單
從element-ui中將Menu菜單的代碼拷貝過來,如下所示:
1.2 準備菜單數據
對其進行循環操作,提前準備一份數據,如下所示:
(1)path: 路由路徑(URL地址)。
(2)name: 路由名稱,用于編程式導航或RouterLink。
(3)label: 菜單上顯示的名稱。
(4)icon: 顯示的圖標(可能使用如 Element Plus, Font Awesome 等圖標庫)。
(5)url: 可能指向對應的組件文件名或組件名稱。
使用了Vue 3的computed(計算屬性)來對一個菜單或樹形結構的列表list進行分類,分別篩選出:
(1)沒有子項的項(葉子節點)。
(2)有子項的項(非葉子節點,通常用于展開的菜單組)。
1.3 循環渲染菜單
圖標+標簽
1.3.1 el-menu結構
<el-menu-item>菜單項</el-menu-item>
<el-sub-menu index="group"><template #title>主標題</template><el-menu-item-group title="分組標題"><el-menu-item index="1">選項1</el-menu-item><el-menu-item index="2">選項2</el-menu-item></el-menu-item-group>
</el-sub-menu>
el-menu-item-group通常嵌套在el-sub-menu或直接放在el-menu內。
1.3.2 動態渲染圖標
需要確保:圖標組件已注冊(全局或局部)。
<component :is="item.icon" class="icons" />
(1)component:是Vue內置的“元組件”,用于動態渲染不同的組件。
(2):is=“item.icon”:綁定is屬性,告訴Vue要渲染哪一個組件。
item.icon應該是一個組件的名稱或組件本身的引用。
(3)class=“icons”:無論渲染哪個組件,都會加上icons這個CSS類。
1.4 樣式設計
1.5 整體代碼(CommonAside.vue)
<template><el-aside width="180px"><el-menu background-color="#545c64"><h3>通用后臺管理系統</h3><el-menu-item v-for="item in noChildren" :index="item.path" :key="item.path"><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></el-menu-item><el-sub-menu v-for="item in hasChildren" :index="item.path" :key="item.path"><template #title><component class="icons" :is="item.icon"></component><span>{{ item.label }}</span></template><el-menu-item-group><el-menu-item v-for="(subItem,subIndex) in item.children" :index="subItem.path" :key="subItem.path"><component class="icons" :is="subItem.icon"></component><span>{{ subItem.label }}</span></el-menu-item></el-menu-item-group></el-sub-menu></el-menu></el-aside>
</template >
<script setup>import {ref,computed} from 'vue'import { useRouter } from 'vue-router';const router = useRouter()const list = ref([{path:"/home",name:"home",label:"首頁",icon:"house",url:"Home"},{path:"/mail",name:"mail",label:"商品管理",icon:"video-play",url:"Mail"},{path:"/user",name:"user",label:"用戶管理",icon:"user",url:"User"},{path:"other",label:"其他",icon:"location",children:[{path:"/page1",name:"page1",label:"頁面1",icon:"setting",url:"Page1"},{path:"/page2",name:"page2",label:"頁面2",icon:"setting",url:"Page2"}]}])const noChildren = computed(()=>list.value.filter(item=>!item.children))const hasChildren = computed(()=>list.value.filter(item=>item.children))
</script>
<style lang="less" scoped> .icons{width: 18px;height: 18px;margin-right: 5px;}.el-menu{border: none;h3{line-height: 48px;color: #333;text-align:center;}}.el-aside{ height: 100%;background-color: #545C64;}
</style>
2 CommonHeader組件(靜態搭建)
左中右三部分:左側是一個圖標,中間是面包屑,右側是dropdown。
2.1 準備圖片URL數據
Vue 3 + Vite項目中動態引入本地靜態資源(如圖片)的推薦方式。
根據傳入的user名稱(如 ‘avatar’),動態生成指向src/assets/img/avatar.png的絕對路徑URL,確保圖片能在生產環境中正確加載。
<script setup>const getImageUrl= (user) => { return new URL(`../assets/img/${user}.png`,import.meta.url).href}
</script>
(1)import.meta.url: 這是一個特殊的元屬性,它返回當前模塊文件(即這個.vue文件)的完整URL。
Vite(Vue常用的構建工具)利用這個信息來計算第一個參數中相對路徑的絕對位置。
(2).href: new URL()返回一個URL對象,.href屬性獲取該對象的完整字符串形式的URL。
這個URL是經過Vite構建系統處理過的,確保在開發和生產環境中都能正確訪問資源(例如,生產環境可能包含哈希值)。
2.2 頁面布局
按鈕、面包屑、下拉菜單。
2.3 樣式設計
(1)display: flex; 啟用Flex布局,讓子元素可以靈活排列。
(2)justify-content: space-between; 主軸方向兩端對齊,第一個子元素靠左,最后一個靠右,中間自動留白。
(3)align-items: center; 交叉軸居中對齊,所有子元素在垂直方向居中。
(4)width: 100%; height: 100%; 占滿父容器的寬高(常用于el-header或類似容器)。
(5)background-color: #333; 深灰色背景,常用于導航欄。
(1):deep(…):Vue提供的深度選擇器(deep selector),用于在scoped樣式中穿透到子組件的內部DOM。
(2).bread span:選擇所有擁有class="bread"的元素內部的span。
(3)color: #fff !important; cursor: pointer !important;:
強制將文字顏色設為白色。
鼠標懸停時顯示為手型指針(可點擊提示)。
2.4 整體代碼(CommonHeader.vue)
<template><div class="header"><div class="l-content"><el-button size="small"><component class="icons" is="menu"></component></el-button><el-breadcrumb separator="/" class="bread"><el-breadcrumb-item :to="{ path: '/' }">首頁</el-breadcrumb-item></el-breadcrumb></div><div class="r-content"><el-dropdown><span class="el-dropdown-link"><img :src="getImageUrl('user')" class="user"/></span><template #dropdown><el-dropdown-menu><el-dropdown-item>個人中心</el-dropdown-item><el-dropdown-item>退出</el-dropdown-item></el-dropdown-menu></template></el-dropdown></div></div>
</template><script setup>const getImageUrl= (user) => { return new URL(`../assets/img/${user}.png`,import.meta.url).href}
</script><style lang="less" scoped> .header{ display: flex;justify-content: space-between;align-items: center;width: 100%;height: 100%;background-color: #333;}.icons{width: 20px;height: 20px;}.l-content{display: flex;align-items: center;.el-button{margin-right: 20px;}}.r-content{.user{width: 40px;height: 40px;border-radius: 50%;}}:deep(.bread span){color:#fff !important;cursor: pointer !important;}
</style>
3 附錄
3.1 列表filter
const list = [1,2,3];
const a = list.filter(item => item != 1);
alert(a);
返回2、3。
3.2 參考附錄
參考elementplus官網地址
參考vue3實現通用后臺管理(傻瓜式一步一步記錄代碼實現過程)
參考js代碼在線運行工具