Vue 菜单导航栏,轮播图

导航菜单栏结构和样式代码实现

一级导航栏
Vue 菜单导航栏,轮播图_第1张图片

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>

Vue 菜单导航栏,轮播图_第2张图片

导航菜单栏接口数据渲染

数据库存储格式
Vue 菜单导航栏,轮播图_第3张图片
Vue 菜单导航栏,轮播图_第4张图片

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)
})

Vue 菜单导航栏,轮播图_第5张图片

//  接口返回数据需要进行加工,基本结构应该是[{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>

Vue 菜单导航栏,轮播图_第6张图片

二级菜单栏的显示与隐藏

需要把二级菜单调到右边覆盖banner
home/leftMenu.vue
Vue 菜单导航栏,轮播图_第7张图片
Vue 菜单导航栏,轮播图_第8张图片

home/SecondMenu.vue
接收一级菜单传递过来的id

<template>
    <div>我是二级菜单xxxxxxxxxxxxxxxxxx {{showSecondMenuIndex}}</div>
</template>


<script setup>
const showSecondMenuIndex = defineProps(["showSecondMenuIndex"])
</script>

鼠标移动会向二级菜单传递一级菜单的ID
Vue 菜单导航栏,轮播图_第9张图片

二级菜单栏的代码开发骨架结构搭建

Vue 菜单导航栏,轮播图_第10张图片
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>

Vue 菜单导航栏,轮播图_第11张图片
Vue 菜单导航栏,轮播图_第12张图片

首页 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>

你可能感兴趣的:(Vue,vue.js)