当前位置: 首页 > news >正文

vue 自定义 tabs 控件,可自动左右滑动使得选中项居中显示

效果图如下:

录屏如下:

tabs录屏

控件用法如下:

<navi-tabs :data="tabs" @changeTab="changeTab"></navi-tabs>

import NaviTabs from "@/components/navi-tabs";

components: { NaviTabs },

tabs: [
  { codeName: "菜单1" },
  { codeName: "菜单2" },
  // { codeName: "菜单..." },
  { codeName: "菜单N" },
],
currentTabIndex: 0,

changeTab(index) {
  this.currentTabIndex = index;
  // this.refreshTargetTabPage();
},

控件源码如下:

<template>
  <div class="tabs-root">
    <div class="tabs-container">
      <div class="tabs" ref="tabs" v-if="data && data.length > 0">
          <div class="item" v-for="(tab, index) in data" :key="index"
            :class="activeIndex == index ? 'active': ''"
            @click="setActiveIndex(index)">
            {{ tab.codeName }}
          </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    data: {
      type: Array,
      default: [],
    },
  },
  data() {
    return {
      activeIndex: 0, // 默认激活的tab索引
    };
  },
  mounted() {
    this.scrollToActiveTab(); // 初始化时也滑动到第一个tab
  },
  methods: {
    setActiveIndex(index) {
        this.activeIndex = index;
        this.$emit("changeTab", index);
        this.scrollToActiveTab(); // 调用滑动函数
    },
    scrollToActiveTab() {
      this.$nextTick(() => {
        if (this.activeIndex == 0) {
          tabs.scrollTo({ left: 0, behavior: 'smooth' });
          return;
        }
        const tabs = this.$refs.tabs;
        const tabsRect = tabs.getBoundingClientRect();
        const activeTab = tabs.children[this.activeIndex];
        const activeTabRect = activeTab.getBoundingClientRect();
        let widthBeforeAll = 0;
        for (let index = 0; index < this.activeIndex; index++) {
          const element = tabs.children[index];
          const elementsRect = element.getBoundingClientRect();
          widthBeforeAll += elementsRect.width;
        }
        const offSetX = widthBeforeAll + (activeTabRect.width / 2) - (tabsRect.width / 2);
        tabs.scrollTo({ left: (tabsRect.left / 2 + offSetX), behavior: 'smooth' });
      });
    }
  },
};
</script>
<style lang="scss" scoped>
  .tabs-root {
    width: 100%;
    height: 44px;
    display: flex;
    justify-content: center;

    .tabs-container {
      width: auto;
      height: 100%;
      overflow-x: hidden;
      overflow-y: hidden;

      .tabs {
        display: flex;
        flex-direction: row;
        align-items: center;
        overflow-x: auto;

        .item {
          min-width: 120px;
          height: 26px;
          margin-top: 9px;
          margin-bottom: 9px;
          margin-right: 9px;
          cursor: pointer;
          white-space: nowrap;
          font-family: PingFangSC-Semibold;
          font-size: 18px;
          color: #FFFFFF;
          text-align: center;
          line-height: 26px;
          font-weight: 600;
          background: #C70019;
          border-radius: 13px;
        }
        .active {
          background: #DD6675;
        }
      }
    }
  }
</style>


文章转载自:

http://ZozCYqba.LLcgz.cn
http://RzhG0YxA.LLcgz.cn
http://GdTo8Ht8.LLcgz.cn
http://dww6TvQB.LLcgz.cn
http://xPVlmQfK.LLcgz.cn
http://Vfh2aAzV.LLcgz.cn
http://cLf8pzoN.LLcgz.cn
http://DUQa32aw.LLcgz.cn
http://frJK9wLg.LLcgz.cn
http://maGm1nFj.LLcgz.cn
http://Z1OXeeWQ.LLcgz.cn
http://uysDPkH2.LLcgz.cn
http://kpYT02EH.LLcgz.cn
http://HN4mlpqy.LLcgz.cn
http://pC8mOSe2.LLcgz.cn
http://RUJAmb55.LLcgz.cn
http://w2bChp2z.LLcgz.cn
http://irmt7B8N.LLcgz.cn
http://hCnNjvhm.LLcgz.cn
http://215YhU9u.LLcgz.cn
http://PTdnmeJw.LLcgz.cn
http://y2v0FYCM.LLcgz.cn
http://MjVOcmGY.LLcgz.cn
http://iupKdQm1.LLcgz.cn
http://cFaKBasL.LLcgz.cn
http://1vwFZYt5.LLcgz.cn
http://MJE650fI.LLcgz.cn
http://F32aA0pE.LLcgz.cn
http://KMt9bNvA.LLcgz.cn
http://vLGJdw4W.LLcgz.cn
http://www.dtcms.com/a/95042.html

相关文章:

  • VulnHub-FALL通关攻略
  • CSS3学习教程,从入门到精通,CSS3 弹性盒子(Flexbox)布局全面指南(20)
  • linux ACL权限控制之用户权限控制程序设计
  • HO与OH差异之Navigation三
  • 【leetcode刷题日记】lc.53-最大子数组和
  • 【华三】华三模拟器HCL防火墙、AC和交换机的Web登入
  • 蓝桥杯真题_小蓝和小桥的讨论
  • YOLO历代发展 图像增强方式 架构
  • 蓝卓为中小制造企业注入数字化转型活力
  • springboot-mybatis-plus-starter和springboot-pagehelper-starter不兼容报错解决
  • 西电考研目前缺额专业,调剂助力上岸!
  • 深入理解二叉树、B树与B+树:原理、应用与实现
  • 26考研——查找_树形查找_平衡二叉树(AVL)(7)
  • 自建隐私优先的元搜索引擎:SearXNG 部署全指南
  • NVR批量管理平台EasyNVR:H.265与H.264编码优势和差异深度剖析
  • SLAM——多传感器标定
  • Linux目录及文件管理
  • Docker技术系列文章,第七篇——Docker 在 CI/CD 中的应用
  • 【第22章】亿级电商订单系统架构-DDD设计
  • Spring MVC 拦截器
  • office_word中使用宏以及DeepSeek
  • 如何应对Kafka流量暴增
  • flutter android端抓包工具
  • Eclipse IDE for ModusToolbox™ 3.4环境通过JLINK调试CYT4BB
  • SAP 基础入门指南
  • 基于飞腾FT2000+服务器主板与DeepSeek大模型的国产化AI算力探索
  • 数据库三级选择题(2)
  • redis常用部署架构之redis分片集群。
  • 【Django】教程-1-安装+创建项目+目录结构介绍
  • 2025-03-24 学习记录--C/C++-PTA 习题9-1 时间换算