效果如图:

菜单

子组件:HeaderTab.vue

<template>
  <div class="header">
    <div class="header_search-left">
      <!-- <slot name="header_tab_img"></slot> -->
    </div>
    <div class="header_tab" ref="headertab">
      <ul ref="tabitem">
        <li
          v-for="(item, index) in listArray"
          :key="index"
          :class="index == current ? 'activeheader' : ''"
          @click="getTab(index, $event)"
        >
          {{ item.name }}
        </li>
      </ul>
    </div>
    <div class="header_search-right">
      <!-- <slot name="header_tab_img"></slot> -->
    </div>
  </div>
</template>
 
<script>
export default {
  name: "HeaderTab",
  props: {
    listArray: {
      type: Array,
    },
  },
  data() {
    return {
      current:1,
    };
  },
  methods: {
    getTab(index, e) {
      this.current = index;   // 高亮当前
      let tab =this.$refs.headertab; // 包裹 ul的 div
      let tabitem = this.$refs.tabitem;    // 包裹 li的 ul
      let winWidth = window.innerWidth;  // 当前屏幕的宽度
      let liList = e.target;   // 当前点击的li
      if (liList) {  //  当前li左偏移, li的宽度, 中间值(当前屏幕的宽度 - li的宽度) /2, 目标值 (中间值 - 当前li左偏移), 整个ul的宽度
        let liLeft = liList.offsetLeft,
          liWidth = liList.offsetWidth,
          liCenter = (winWidth - liWidth) / 2,
          liTarget = liLeft - liCenter;
        let ulWidth = tabitem.offsetWidth;
        if (liTarget < 0) {
          tab.scrollLeft = 0;
          return;
        }
        // winWidth(375) - ulWidth(436) =  -61
        if (liTarget < winWidth - ulWidth) {
          tab.scrollLeft = -(winWidth - ulWidth) + liWidth;
          return;
        }
        tab.scrollLeft = liTarget;
      }
    },
  },
};
</script>
<style lang="less" scoped>
  .header {
    width: 100%;
    height: 40px;
    background-color: #fff;
    display: flex;
    border-radius: 8px;
    position: relative;
    overflow: hidden;
  }
  .header_tab {
    width: 90%;
    height: 40px;
    display: flex;
    flex-wrap: nowrap;
    overflow: scroll;
    padding-left: 19px;
    padding-right: 19px;
    // 平滑滚动
    transition: all 0.05s linear;
    scroll-behavior: smooth;
  }
  .header_tab::-webkit-scrollbar {
    display: none;
  }
  ul {
    display: inline-block;
    white-space: nowrap;
    margin: 0;
    padding-left: 0;
    padding-right: 19px;
    height: 40px;
  }
  li {
    display: inline-block;
    height: 40px;
    line-height: 40px;
    padding: 0px 10px;
    font-size: 14px;
    color: #333;
    // 点击高亮某一项时,将原来的字体变大,会导致没有高亮的元素距离底部有空隙,会出现纵向滚动条
    // margin-top: -1px;
  }
  .activeheader {
    font-size: 14px;
    color: #2b96ff;
    // font-weight: 700;
    position: relative;
    &:after {
      position: absolute;
      content: "";
      width: 18px;
      height: 2px;
      bottom: 0;
      left: calc(50% - 9px);
      background-color: #2b96ff;
	    border-radius: 1px;
    }
  }
  
  .header_search-left {
    width: 25px;
    height: 40px;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 1000;
    background-image:-webkit-linear-gradient(  
    to right,   
    rgba(255,255,255,1) 0%,   
    rgba(255,255,255,1) 55%,   
    rgba(255,255,255,1) 70%,
    rgba(255,255,255,0.8) 80%,   
    rgba(255,255,255,0.3) 90%,   
    rgba(255,255,255,0.1) 100%);    
  background-image: linear-gradient(  
    to right,   
    rgba(255,255,255,1) 0%,   
    rgba(255,255,255,1) 55%,
    rgba(255,255,255,1) 70%,  
    rgba(255,255,255,0.8) 80%,   
    rgba(255,255,255,0.3) 90%,   
    rgba(255,255,255,0.1) 100%);
    img {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      margin: auto;
    }
  }

  .header_search-right {
    width: 25px;
    height: 40px;
    position: absolute;
    top: 0;
    right: 0;
    z-index: 1000;
    background-image:-webkit-linear-gradient(  
    to left,   
    rgba(255,255,255,1) 0%,   
    rgba(255,255,255,1) 55%,
    rgba(255,255,255,1) 70%,  
    rgba(255,255,255,0.8) 80%,   
    rgba(255,255,255,0.3) 90%,   
    rgba(255,255,255,0.1) 100%);    
  background-image: linear-gradient(  
    to left,   
    rgba(255,255,255,1) 0%,   
    rgba(255,255,255,1) 55%,
    rgba(255,255,255,1) 70%,  
    rgba(255,255,255,0.8) 80%,   
    rgba(255,255,255,0.3) 90%,   
    rgba(255,255,255,0.1) 100%);
    img {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      margin: auto;
    } 
  }
</style>

父组件:

<header-tab :listArray="list">
   <!-- <img :src="imgSrc" alt="" slot="header_tab_img" /> -->
</header-tab>

import HeaderTab from '@/views/template/components/HeaderTab'

export default {
    name: '',
    components: {
        HeaderTab,
    },
    data() {
        return {
            list:[
                { id: 1, name: "分级分类记录" },
                { id: 2, name: "吸毒检测记录" },
                { id: 3, name: "家访记录" },
                { id: 4, name: "风险评估记录" },
                { id: 5, name: "毛发检测结果记录" },
                { id: 6, name: "报备记录" },
            ],
        }
    },
};

代码已经贴的很明白的,如果有问题自行解决,懂!

GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5 * chore: fix link broken Signed-off-by: snoppy <michaleli@foxmail.com> * Update packages/template-compiler/README.md [skip ci] --------- Signed-off-by: snoppy <michaleli@foxmail.com> Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891 Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐