分享一个 VUE 侧边导航共用组建

项目效果图:

项目描述:加载组建时,隐藏,鼠标滑动到指定区域的时候该菜单选中高亮,点击菜单跳转到指定模块,每个页面都适用。
分享一个 VUE 侧边导航共用组建_第1张图片

html 部分:

提示:我这里有英文所以有$i18n.locale==='zh' 判断,使用的时候按照个人项目情况使用。

 <div class="left-nav-box" ref="nav-box">
    <div class="nav">
      <div class="line">
        <div class="sub-line active" :style="`margin-top: ${active*0.152}rem`"></div>
      </div>
      <ul>
        <li v-for="(item,index) in menu"
            :key="item.name" @click="tabClick(item,index)"
            :style="`color:${active===index?'#fff':'rgba(255, 255, 255, 0.70)'}`"
        >
          {{ $i18n.locale === 'zh' ? item.title : item.titleEn }}
        </li>
      </ul>
    </div>
  </div>

css部分:

.left-nav-box {
  position: fixed;
  top: 220px;
  left: 20px;
  z-index: -1;
  //display: none;
  opacity: 0;
  transition: 0.3s ease-in-out;
}

.line {
  background: rgba(255, 255, 255, 0.26);
  width: 4px;
  border-radius: 4px 4px 4px 4px;
  overflow: hidden;

  .sub-line {
    width: 4px;
    height: 32px;
    background: #1874F6;
    border-radius: 4px;
  }
}

.active {
  transition: 0.3s ease-in-out;
}

.nav {
  display: flex;
  padding: 12px;
  font-size: 15px;
  min-width: 200px;
  background: rgba(0, 0, 0, 0.26);
  border-radius: 4px 4px 4px 4px;
  opacity: 1;
  border: 1px solid rgba(255, 255, 255, 0.3);
  backdrop-filter: blur(25px);

  ul {
    width: 100%;
  }

  li {
    width: 100%;
    font-weight: 700;
    color: rgba(255, 255, 255, 0.7);
    display: block;
    cursor: pointer;

    &:hover {
      color: #fff;
    }

    margin-bottom: 9px;
    margin-left: 12px;

    &:last-child {
      margin-bottom: 0;
    }
  }
}

侧边栏json部分:

//注意:1: 数组的key名,需要根据组建的name来设置
//     2: 侧边菜单什么时候出现需要,在使用的组建中设置 id = 组建的name
//     3: 点击的链接需要在组建中设置 id= name.url(name:组建的name即home.url)
//     4: 需要在页面显示,设置菜单json数组就可以了
export default {
    home:[
        {url:'tab1',title:"xxxx",titleEn:"xxxx"},
        {url:'tab2',title:"xxxx",titleEn:"xxxx"},
    ]
}

js部分:

import menu from "../LeftTabs/leftMenu"
export default {
  name: "leftNav",
  data() {
    return {
      menuLeft: menu,
      active: 0,
      num: 0,
      top: []
    }
  },
  props: {
    menu: {
      type: Array,
      default: []
    },
    startMouse: {
      type: String,
      default: '#tab1'
    }
  },
  mounted() {
    this.getLoad();
  },
  watch: {
    $route: {
      handler: function () {
        this.getLoad()
      }
    }
  },
  methods: {
    getLoad() {
      this.top = [];
      if (this.menuLeft[this.$route.name]) {
        this.menuLeft[this.$route.name].forEach((item, index) => {
          this.num = index;
          //获取每个侧边菜单距离顶部的距离
          this.top[index] = document.getElementById(item.url).offsetTop;
        })
        window.addEventListener("scroll", this.scrollDown)
      } else {
        window.removeEventListener('scroll', this.scrollDown)
      }
    },
    scrollDown() {
      //获取从哪里开始显示侧边栏
      let top = document.getElementById(this.startMouse);
      if (top) {
        let scrollTop =
            window.pageYOffset ||
            document.documentElement.scrollTop ||
            document.body.scrollTop;
        //获取菜单的每一项的小于鼠标滑动的距离顶部的高度
        let item = this.top.filter(item => item < scrollTop);
        // 排序取最大的一个
        let numTxt = item.sort((a, b) => b - a)[0];
         // 取最大的一个的索引
        let index = this.top.findIndex(item => item === numTxt);
        // 默认选中
        this.active = isUndefined(numTxt) ? 0 : (numTxt < scrollTop ? index : this.num);
        if (top.offsetTop < scrollTop) {
          this.mouseShow();
        } else {
          this.mouseHide();
        }
      }
    },
    tabClick(item, index) {
      this.active = index;
      let tab = document.getElementById(item.url);
      tab?.scrollIntoView();
    },
    mouseShow() {
      let flag = this.$refs["nav-box"];
      flag.style.opacity = '1';
      flag.style.zIndex = '2004';
    },
    mouseHide() {
      let flag = this.$refs["nav-box"];
      flag.style.opacity = '0';
      flag.style.zIndex = '-1';
    }
  }
}

应用:

提示:这里我是写在全局的layout里面,因为的的项目用的地方比较多。可根据自己的项目更改

import leftMenu from '@/components/LeftTabs/leftMenu'

<leftNav :menu="menuList"
         :startMouse="start"  
         v-if="menuList!==''"
/>

export default {
  data() {
    return {
      menuList:leftMenu[this.$route.name],
      start:this.$route.name,
      show: true
    }
  },
  components: {
    leftNav
  },
  mounted() {
    this.getList();
  },
  watch: {
    $route: {
      handler: function () {
        this.getList();
      },
      deep:true
    },
  },
  methods:{
    getList(){
      this.menuList = leftMenu[this.$route.name] || "";
      this.start = this.$route.name;
    }
  }
}
//id="home" 一定要组建的name
 <div class="home-top" id="home">
 </div>
 //锚点滚动到指定位置,此id需要在json数组中的url定义的一致
  <div class="home-tab1" id="tab1">
 </div>
  <div class="home-tab2" id="tab2">
 </div>

总结:

好记性, 不如乱笔头,记个笔记。
第一:可能自己以后能用到
第二:可能帮助到有需要的人

你可能感兴趣的:(TypeScript,vue3,vue.js,css3,css)