手写tab选中

html 复制代码
<div class="appBox">
   <div class="navBox">
     <p class="navItemBox" v-for="(item) in navList" :key="item.id" :class="activeNav == item.id ? 'activeText':''"
       @click="scrollToTarget(item.id)">
       <span>{{item.title}}</span>
     </p>
   </div>

   <div class="navContentBox">
     <div id="allApp" class="content-section">
       全部
     </div>
     <div id="app1" class="content-section">
       应用1
     </div>
     <div id="app2" class="content-section">
       应用2
     </div>
     <div id="app3" class="content-section">
       应用3
     </div>
     <div id="app4" class="content-section">
       应用4
     </div>
   </div>
</div>


<script setup>
import { ref, onMounted, reactive, } from 'vue'
// import { queryJgAPI, } from '@/api/instruct'
import { ElMessage, ElMessageBox } from 'element-plus';

// 记录当前激活的导航项(可选,用于高亮)
const activeNav = ref('allApp');

const navList = ref([
  { id:'allApp', title: '全部', },
  { id:'app1', title: '应用1', },
  { id:'app2', title: '应用2', },
  { id:'app3', title: '应用3', },
  { id:'app4', title: '应用4', },
])

const state = reactive({})

// 核心滚动方法
const scrollToTarget = (key) => {
  // 1. 更新激活状态(高亮当前项)
  activeNav.value = key;
  // 2. 找到右侧目标元素
  const target = document.getElementById(key);
  if (target) {
    // 3. 平滑滚动到目标元素
    target.scrollIntoView({
      behavior: 'smooth', // 平滑滚动(去掉则立即跳转)
      block: 'start' // 对齐到元素顶部(可选:center/end)
    });
  }
};

onMounted(()=>{})
</script>
<style>
.appBox{
   width: 100%;
   height: 100%;
   background-color: #fff;

   .navBox{
     display: flex;
     gap: 40px;
     align-items: center;
     padding: 8px 30%;
     font-weight: 600;

     .navItemBox{
       position: relative;
       padding: 10px;
     }
   }
   .activeText{
     &:after{
       content: '';
       display: block;
       position: absolute;
       bottom: 0;
       left: 50%;// 从中间开始
       transform: translateX(-50%);// 向左偏移自身宽度的一半,实现居中
       width: 40px; // 默认宽度为 0
       height: 3px;
       border-radius: 2px;
       transition: width 0.3s ease;  
       background-color: #426deb;
     }
   }

   .navContentBox{
     height: 98%;
     overflow: auto;
     
     .content-section{
       height: 40%;
       // background-color: pink;
     }
   }
 }
</style>
相关推荐
勇往直前plus2 小时前
Vue3(篇一) 核心概念——响应式模板语法与组件基础
前端·javascript·vue.js
咩咩啃树皮2 小时前
第43篇:Vue3计算属性(computed)完全精讲——缓存机制、依赖计算、业务最优解
前端·vue.js·缓存
用户938515635073 小时前
从零搭建 AI 日记助手:用 Milvus 向量数据库 + RAG 让机器读懂你的每一天
javascript·人工智能·全栈
徐小夕4 小时前
花了一周,3亿tokens,我开源了一款 Word 文档智能审查平台,文稿自动质检+可视化分析,告别低效人工审核
前端·算法·github
a1117765 小时前
坦克大战3D Three.js 3D (开源项目)
开发语言·javascript·3d
kyriewen5 小时前
别再乱用useEffect了——你写的10个里有8个不该存在
前端·javascript·react.js
Ivanqhz6 小时前
Rust &‘static str浅析
java·前端·javascript·rust
IT_陈寒6 小时前
SpringBoot这个分页坑,我踩了三天才爬出来
前端·人工智能·后端
颜酱6 小时前
05 | 召回前置准备:根据业务数据库生成各数据库(读取配置阶段)
前端·人工智能·后端
zandy10117 小时前
衡石 Agentic BI的ReAct 推理框架在 Agentic BI 中的工程化实践
前端·javascript·react.js