导航菜单栏结构和样式代码实现
一级导航栏
views/HomeView.vue
<template><div><Shortcut></Shortcut><Header></Header><div class="inner"><Navigation></Navigation></div><div>我是主页</div></div>
</template><script setup>
import Shortcut from "@/components/common/Shortcut.vue"
import Header from "@/components/home/Header"
import Navigation from "@/components/home/Navigation"</script><style lang="less" scoped>.inner{background-color: #f4f4f4;}
</style>
src/components/home/navigation.vue
<template><div class="nav "><div class="main clearfix"><div class="menu fl"><LeftMenu></LeftMenu></div><div class="banner fl">我是banner</div></div></div>
</template><style lang="less" scoped>
.nav {.main {padding-top: 15px;width: var(--content-width);margin: 0 auto;}
}
</style><script setup>
import LeftMenu from "./LeftMenu.vue";
</script>
src/components/home/leftmenu.vue
<template><div class="left-menu"><ul><li><span><a href="">手机</a><span>/</span><a href="">运营商</a><span>/</span><a href="">数码</a></span></li></ul><div class="second-item">我是二级菜单</div></div>
</template><style scoped lang="less">
@red: #e2231a;
.left-menu {// text-align: left;// float: left;background-color: #fff;width: 190px;height: 470px;ul {padding-top: 15px;li {padding-top: 5px;padding-bottom: 5px;padding-left: 15px;&:hover {cursor: pointer;background-color: #d9d9d9;}a {font-size: 14px;color: #333;&:hover {cursor: pointer;color: @red;}}}}
}
</style>
导航菜单栏接口数据渲染
数据库存储格式
let leftMenuData=ref([])
onMounted(()=>{getMainMenu().then(res=>{console.log(res.data)init_menu_data(res.data)})
})
根据main_menu_id判断菜单名在哪一行
const init_menu_data=(menuData=>{for(let i in menuData){let jsonData = JSON.parse(menuData[i])leftMenuData.value.push(jsonData) }console.log(leftMenuData)
})
// 接口返回数据需要进行加工,基本结构应该是[{index:1,data:[{name,url},{},{}]}]const showMainData=computed(()=>{let resultList = [];let result = {"index":"","data":[]};for(let i in leftMenuData.value){let id = leftMenuData.value[i].main_menu_id;let data = {"name":leftMenuData.value[i].main_menu_name};if(result["index"] != null && id == result["index"]){result["data"].push(data);}else{result = {"index":"","data":[]};result["index"] = id;result["data"].push(data);resultList.push(result);}}return resultList;})
完整代码
<template><div class="left-menu"><ul><li v-for="(item,index) in showMainData" :key="index"><span v-for="(d,i) in item.data" :key="i"><a href="">{{d.name}}</a><!-- 删除多余的斜线 --><span v-if="item.data.length-i-1">/</span></span></li></ul><div class="second-item">我是二级菜单</div></div>{{showMainData}}
</template><style scoped lang="less">
@red: #e2231a;
.left-menu {// text-align: left;// float: left;background-color: #fff;width: 190px;height: 470px;ul {padding-top: 15px;li {padding-top: 5px;padding-bottom: 5px;padding-left: 15px;&:hover {cursor: pointer;background-color: #d9d9d9;}a {font-size: 14px;color: #333;&:hover {cursor: pointer;color: @red;}}}}
}
</style><script setup>
import {getMainMenu} from "@/network/home.js"
import {onMounted, ref,computed} from "vue"let leftMenuData=ref([])
onMounted(()=>{getMainMenu().then(res=>{init_menu_data(res.data)})
})const init_menu_data=(menuData=>{for(let i in menuData){let jsonData = JSON.parse(menuData[i])leftMenuData.value.push(jsonData) }
})// 接口返回数据需要进行加工,基本结构应该是[{index:1,data:[{name,url},{},{}]}]const showMainData=computed(()=>{let resultList = [];let result = {"index":"","data":[]};for(let i in leftMenuData.value){let id = leftMenuData.value[i].main_menu_id;let data = {"name":leftMenuData.value[i].main_menu_name};if(result["index"] != null && id == result["index"]){result["data"].push(data);}else{result = {"index":"","data":[]};result["index"] = id;result["data"].push(data);resultList.push(result);}}return resultList;})
</script>
二级菜单栏的显示与隐藏
需要把二级菜单调到右边覆盖banner
home/leftMenu.vue
home/SecondMenu.vue
接收一级菜单传递过来的id
<template><div>我是二级菜单xxxxxxxxxxxxxxxxxx {{showSecondMenuIndex}}</div>
</template><script setup>
const showSecondMenuIndex = defineProps(["showSecondMenuIndex"])
</script>
鼠标移动会向二级菜单传递一级菜单的ID
二级菜单栏的代码开发骨架结构搭建
home/SecondMenu.vue
<template><div class="second"><div class="menu-content"><div class="menu-title"><span><a href=""> 家电馆<img src="@/assets/images/menu/arrows-white.png" alt="" /></a></span></div><div class="menu-detail"><div class="menu-detail-item"><span><span><span class="menu-detail-tit"><a href="">电视<img src="@/assets/images/menu/arrows-black.png" alt="" /></a></span><span class="menu-detail-data"><a href="">全面屏电视</a></span></span></span></div></div></div></div>
</template><script setup>
const showSecondMenuIndex = defineProps(["showSecondMenuIndex"]);
</script><style lang="less" scoped>
</style>
二级菜单栏的代码开发页面样式渲染
<template><div class="second"><div class="menu-content"><div class="menu-title"><span><a href="">家电馆<img src="@/assets/images/menu/arrows-white.png" alt="" /></a></span></div><div class="menu-detail"><div class="menu-detail-item"><span><span class="menu-detail-tit"><a href="">电视<img src="@/assets/images/menu/arrows-black.png" alt="" /></a></span><span class="menu-detail-data"><a href="">全面屏电视</a></span></span></div></div></div></div>
</template><script setup>
const showSecondMenuIndex = defineProps(["showSecondMenuIndex"]);
</script><style lang="less" scoped>
@red: #e2231a;
.second {width: 1000px;background-color: #fff;border: 2px solid #e9e9e9;padding: 20px;.menu-content {margin-right: 900px;.menu-title {a {display: inline-block;background-color: black;color: white;margin-right: 10px;height: 25px;line-height: 25px;padding: 0 10px;img {height: 18px;}&:hover {background-color: @red;}}}.menu-detail {margin-top: 15px;.menu-detail-item {.menu-detail-tit {a {font-weight: 700;img {height: 18px;}&:hover {color: @red;}}}.menu-detail-data {a {margin-left: 20px;&:hover {color: @red;}}}}}}
}
</style>
二级菜单栏的接口数据渲染
home/secondMenu.vue
<template><div class="second"><div class="menu-content" v-for="(item,index) in showSubMenuData" :key="index"><div class="menu-title"><span v-for="(d,i) in item.data" :key="i"><a href="" v-show="d.type==='channel'">{{d.name}}<img src="@/assets/images/menu/arrows-white.png" alt="" /></a></span></div><div class="menu-detail"><div class="menu-detail-item"><span v-for="(d,i) in item.data" :key="i"><span class="menu-detail-tit" v-if="d.type==='dt'"><a href="">{{d.name}}<img src="@/assets/images/menu/arrows-black.png" alt="" /></a></span><span class="menu-detail-data" v-else-if="d.type==='dd'"><a href="">{{d.name}}</a></span></span></div></div></div></div>
</template><script setup>
import { getSecondMenu } from "@/network/home.js";
import { ref, watch,computed } from "vue";const showSecondMenuIndex = defineProps(["showSecondMenuIndex"]);
watch(showSecondMenuIndex, (newVlue, oldValue) => {getSecondMenu(newVlue.showSecondMenuIndex).then((res) => {initMenuData(res.data);});
});let subMenuData = ref([]);
const initMenuData = (menuData) => {// 每次初始化的时候 必须把subMenuData设置为空 不然数据会累加subMenuData.value = [];for (let i in menuData) {let jsonData = JSON.parse(menuData[i]);subMenuData.value.push(jsonData);}
};const showSubMenuData = computed(() => {let resultList = [];let result = { index: "", data: [] };for (let i in subMenuData.value) {let id = subMenuData.value[i].sub_menu_id;let data = {name: subMenuData.value[i].sub_menu_name,type: subMenuData.value[i].sub_menu_type,};if (result["index"] != null && id == result["index"]) {result["data"].push(data);} else {result = { index: "", data: [] };result["index"] = id;result["data"].push(data);resultList.push(result);}}return resultList;
});
</script><style lang="less" scoped>
@red: #e2231a;
.second {width: 1000px;background-color: #fff;border: 2px solid #e9e9e9;padding: 20px;.menu-content {// margin-right: 80px;.menu-title {a {display: inline-block;background-color: black;color: white;margin-right: 10px;height: 25px;line-height: 25px;padding: 0 10px;img {height: 18px;}&:hover {background-color: @red;}}}.menu-detail {margin-top: 15px;.menu-detail-item {.menu-detail-tit {a {font-weight: 700;img {height: 18px;}&:hover {color: @red;}}}.menu-detail-data {a {margin-left: 20px;&:hover {color: @red;}}}}}}
}
</style>
首页 Banner 图效果开发
home/banner
<template><div class="block" style="width: 1000px;"><span class="demonstration"></span><el-carousel trigger="click" height="470px"><el-carousel-item v-for="item in images" :key="item"><img :src="item" alt=""></el-carousel-item></el-carousel></div>
</template><script setup>
import banner1 from "@/assets/images/banner/banner1.png";
import banner2 from "@/assets/images/banner/banner2.png";
import banner3 from "@/assets/images/banner/banner3.png";
import banner4 from "@/assets/images/banner/banner4.png";
import banner5 from "@/assets/images/banner/banner5.png";
import banner6 from "@/assets/images/banner/banner6.png";
import { ref } from "vue";const images=ref([banner1,banner2,banner3,banner4,banner5,banner6])</script><style scoped>.el-carousel__item h3 {color: #475669;font-size: 14px;opacity: 0.75;line-height: 150px;margin: 0;}.el-carousel__item:nth-child(2n) {background-color: #99a9bf;}.el-carousel__item:nth-child(2n + 1) {background-color: #d3dce6;}
</style>
home/Navigation.vue
<template><div class="nav "><div class="main clearfix"><div class="menu fl"><LeftMenu></LeftMenu></div><div class="banner fl"><Banner></Banner></div></div></div>
</template><style lang="less" scoped>
.nav {.main {padding-top: 15px;width: var(--content-width);margin: 0 auto;}
}
</style><script setup>
import LeftMenu from "./LeftMenu.vue";
import Banner from "./Banner.vue";
</script>