tabControl+滚动到锚点

tab栏实现

TabControl.vue

<template>
  <div class="TabControl">
    <ul>
      <li v-for="(item, index) in tabsTitle" :key="index" @click="handleClikc(index)"
        :class="{ active: index === curIndex }">
        {{ item }}</li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
const props = defineProps({
  tabsTitle: {
    type: Array,
    default: () => []
  }
})

// 抛出自定义事件
const emits = defineEmits(['clickTab'])
// 当前下标
let curIndex = ref(0)
function handleClikc(index) {
  curIndex.value = index
  emits('clickTab', index)
}


</script>

<style scoped lang="less">
.TabControl {
  ul {
    display: flex;
    overflow-y: auto;

    li {
      padding: 4px 10px;
    }
  }
}

.active {
  border-bottom: 2px solid var(--primary-color);
}
</style>

点击tab滚动到指定位置

  1. 给tab栏组件传入tab数组
    在这里插入图片描述
  2. 获取各个组件实例
    在这里插入图片描述
  3. 点击tab,监听scrollTop
// 1.滚动到300px 显示tab栏
const { isBottom, scrollTop, clientHeight, scrollHeight } = useScroll()
const showTabs = computed(() => {
  return scrollTop.value > 300
})

// 2.getSectionRef获取绑定了ref属性的组件的根元素
// value为绑定了ref属性的proxy对象
let sectionEls = []
function getSectionRef(value) {
  if (!value) return
  // value.$el 获取当前组件的根元素
  sectionEls.push(value.$el)
  sectionEls = [...new Set(sectionEls)]
}

// 3.点击tab 滑动到对应位置
// scrollTo为DOM相关API
function clickTab(index) {
  window.scrollTo({
    top: sectionEls[index].offsetTop,
    behavior: 'smooth'
  });
}

滚动到指定位置tab栏切换

// 监听页面滚动 匹配到对应tab的下标

// 监听scrollTop变化,找到第一个offset(当scrollTop>=某个tab所对应的offset时),保存该offset对应的tab的下标index
// 例如 scrollTop=600 offsetArr=[100,300,800,1000] 800>=600 则保存300所对应的下标1 
//      scrollTop=6000 返回下标offsetArr.length-1
//      scrollTop=6    返回下标-1
let tabRef = ref()
watch(scrollTop, (newVal) => {
  // 遍历各个位置的范围区间
  const valueArr = sectionEls.map(el => el.offsetTop).slice(0, sectionEls.length)

  let index = valueArr.length - 1
  for (let i = 0; i < valueArr.length; i++) {
    // 26为tab栏高度 避免遮挡
    if (valueArr[i] >= newVal + 26) {
      index = i - 1
      break
    }
  }

  // 修改tab组件的当前下标
  tabRef.value.curIndex = index
})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值