自学内容网 自学内容网

VUE tab栏选中状态与滚动项展示状态对应

实现效果

请添加图片描述

实现思路

  1. 记录滚动容器、滚动项的ref
  2. 点击某一项tab时,滚动对应项到界面上
  3. 监听滚动容器滚动,计算展示在界面的滚动项,选中对应tab项

关键代码

html

<!-- tab栏 -->
<a-tabs id="template-tab" v-model:activeKey="activeKey" tab-position="left" @change="onChangeTab">
    <a-tab-pane v-for="tab in tabs" :key="tab.value" :tab="tab.name"></a-tab-pane>
</a-tabs>
<!-- 滚动容器 -->
<div ref="scrollEl">
<!-- 滚动项 -->
    <div
    v-for="(list, index) in ListByTab"
        :ref="(res) => setTabListRef(index, res)"
        :key="index"
    ></div>
<div>

ts

const activeKey = ref<number>(0);
const tabs = ref([{ ...defaultTab }]);
const tabListRefs = ref<any[]>([]);
const scrollEl = ref();
const { y } = useScroll(scrollEl);
const ListByTab = ref<Item[][]>([[]]);
const tabChanging = ref<boolean>(true);


function onChangeTab(tabKey: number) {
    tabChanging.value = false;
    keyword.value = '';
    nextTick(() => {
        let el = tabListRefs.value[tabKey]?.$el;
        if (tabListRefs.value[tabKey] instanceof HTMLElement) {
            el = tabListRefs.value[tabKey];
        }
        el?.scrollIntoView?.({ block: 'start' });
        tabChanging.value = true;
    });
}

function setTabListRef(index: number, res: any) {
    tabListRefs.value[index] = res;
}

/**
 * 滑动后更新选中哪个分组
 */
const updateActiveTab = throttle(() => {
    const { top: scrollTop, height: scrollHeight } = scrollEl.value.getBoundingClientRect();

    for (const [index, el] of tabListRefs.value.entries()) {
        let realEl: any;
        if (el instanceof HTMLElement) {
            realEl = el;
        } else {
            realEl = el?.$el;
        }
        if (realEl) {
            const { top, height } = realEl.getBoundingClientRect();
            if (top + height > scrollTop + scrollHeight * 0.66 || top >= scrollTop) {
                if (activeKey.value === index) {
                    break;
                } else {
                    // 选中界面上大于2/3的前一项,或者有标题的后一项
                    const leftTabElement = document.getElementById('template-tab');
                    if (leftTabElement) {
                        const divElements = leftTabElement.querySelectorAll('div');
                        divElements.forEach((element: any) => {
                            element.blur(); // 取消之前选中的hover
                        });
                    }
                    activeKey.value = index;
                    break;
                }
            }
        }
    }
}, 500);

watch(
    () => y.value,
    () => {
        if (tabChanging.value) {
            updateActiveTab();
        }
    },
);

原文地址:https://blog.csdn.net/xX20010124/article/details/143723876

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!