在 Vue 中创建可重用的选项卡组件

网页或个人设备上最常用的 UX 元素之一是标签。在本指南中,让我们看看如何使用 Vue Composition API 制作可重用的选项卡组件。这组选项卡可以在您喜欢的任何项目中轻松导入、使用和设置样式,这意味着当您想要实现自己的一组选项卡时,您无需三思而后行。

您可以通过此链接在 GitHub 上找到 Vue Tabs 的源代码

Vue 新手?

如果您是 Vue 新手,我建议您在阅读本指南之前 查看我的入门指南并制作您的第一个 Vue 应用程序。

创建可重用的 Vue 选项卡组件#

选项卡本质上由两部分组成 –选项卡本身和包含所有选项卡的容器。因此,首先,我将在我们的 Vue 文件结构中创建两个文件 –Tab.vueTabs.vue. 我们这个组件的基本文件结构将如下所示:

|- src
|-- App.vue
|-- main.js
|-- components
|--- Tabs.vue
|--- Tab.vue
|- index.html
|- README.md
|- package.json

所以让我们从创建我们的Tab.vue文件开始。我们使用composition API来制作这些选项卡,因此我们的代码比使用 Options API 时要简单一些。您可以在此处了解 Composition 和 Options API 之间的区别

Tab.vue

<script setup>
  import { ref, onMounted } from 'vue';
  const props = defineProps([ 'active' ]);
</script>

<template>
  <div class="tab" :class="(active == 'true') ? 'active' : ''">
    <slot></slot>
  </div>
</template>

<style>
  .tab {
    display: none;
  }
  .tab.active {
    display: block;
  }
</style>

单个选项卡的代码相对简单。我们的标签将有一个属性 – active。此属性将定义选项卡是否应显示。在我们的标签中,我们放了一个slot. 这样我们就可以Tab在我们开始定义自定义内容时为其定义自定义内容。最后,我们有一些 CSS 可以根据它们是否处于活动状态来显示或隐藏选项卡。

现在我们有了一个Tab,让我们尝试为多个选项卡创建一个容器,我已将其放入Tabs.vue文件中。

Tab.vue

让我们从定义我们的脚本开始。我们需要在这里解决的有趣问题是选项卡由选项卡本身组成,然后是您单击以访问该特定选项卡的选项卡。因此,我们需要拉起我们的子标签,并为每个标签创建标题。让我们首先定义我们的脚本来做到这一点。

<script setup>
    import { ref, onMounted } from 'vue';
    const props = defineProps([ 'customClass' ]);

    // Defining our reactive `data()` properties
    let tabContainer = ref(null);
    let tabHeaders = ref(null);
    let tabs = ref(null);
    let activeTabIndex = ref(0);

    onMounted(() => {
        tabs.value = [ ...tabContainer.value.querySelectorAll('.tab') ];
        for(let x of tabs.value) {
            if(x.classList.contains('active')) {
                activeTabIndex = tabs.value.indexOf(x);
            }
        }
    });
</script>

本质上,我们必须通过引用从选项卡容器中收集我们的选项卡。稍后我们将把它附加ref到我们的模板标签上。现在,让我们定义变量。然后我们需要某种方式来获取所有不同的“选项卡标题”,所以现在让我们定义该变量。我们还需要在某个地方存储我们的标签,该标签位于tabs.

最后,我们需要一种方法来跟踪哪个选项卡处于活动状态,这将是我们的activeTabIndex. 在组合 API 中,我们使用ref. 如果您熟悉 Options API,那么这些变量中的大多数都会在data()函数中出现。

当我们挂载我们的组件时,我们运行`onMounted(),并查询所有选项卡。这让我们可以做两件事:

  • 现在,我们可以通过一个简单的变量访问所有选项卡。
  • 我们可以找出当前处于活动状态的选项卡,并正确设置变量。

更改选项卡

我们还需要一个附加功能,用于当用户更改选项卡时。此功能只是隐藏所有当前活动的元素,然后将active类添加到活动的标题和选项卡中。

    const changeTab = (index) => {
        // Set activeTabIndex item to the index of the element clicked
        activeTabIndex = index;
        // Remove any active classes
        for(let x of [...tabs.value, ...tabHeaders.value]) {
            x.classList.remove('active')
        }
        // Add active classes where appropriate, to the active elements!
        tabs.value[activeTabIndex].classList.add('active')  
        tabHeaders.value[activeTabIndex].classList.add('active')  
    }

把它放在我们的模板中

现在我们已经设置好了脚本,让我们制作模板和样式。由于我们已将所有选项卡收集到tabs变量中,因此我们将使用v-for. 我们还将点击事件附加到每个选项卡标题。

注意:这也是我们添加引用的地方。所以我们的变量 ,tabContainer现在绑定到#tabs-container,因为我们添加了 reftabContainer到它。也是如此tabHeaders

<template>
    <div id="tabs-container" :class="customClass" ref="tabContainer">
        <div id="tab-headers">
        <ul>
            <!-- this shows all of the titles --> 
            <li v-for="(tab, index) in tabs" :key="index" :class="activeTabIndex == index ? 'active' : ''" @click="changeTab(index)" ref="tabHeaders"></li>
        </ul>
        </div>
        <!-- this is where the tabs go, in this slot -->
        <div id="active-tab">
            <slot></slot>
        </div>
    </div>
</template>

<style>
    #tab-headers ul {
        margin: 0;
        padding: 0;
        display: flex;
        border-bottom: 2px solid #ddd;
    }
    #tab-headers ul li {
        list-style: none;
        padding: 1rem 1.25rem;
        position: relative;
        cursor: pointer;
    }
    #tab-headers ul li.active {
        color: #008438;
        font-weight: bold;
    }
    
    #tab-headers ul li.active:after {
        content: '';
        position: absolute;
        bottom: -2px;
        left: 0;
        height: 2px;
        width: 100%;
        background: #008438;
    }
    #active-tab, #tab-headers {
        width: 100%;
    }
    
    #active-tab {
        padding: 0.75rem;
    }
</style>

将所有内容整合到一个视图中#

现在我们有了两个组件,我们可以在任何我们喜欢的地方通过导入并使用它们来实现我们的选项卡。我们需要给每个Tab标题属性,它将充当您单击的选项卡的标题。将选项卡添加到您的站点后如下所示:

<script setup>
    import Tabs from './components/Tabs.vue'
    import Tab from './components/Tab.vue'
</script>

<template>
    <Tabs>
        <Tab active="true" title="First Tab">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce gravida purus vitae vulputate commodo.
        </Tab>
  	    <Tab title="Second Tab">
            Cras scelerisque, dolor vitae suscipit efficitur, risus orci sagittis velit, ac molestie nulla tortor id augue.
        </Tab>
  	    <Tab title="Third Tab">
            Morbi posuere, mauris eu vehicula tempor, nibh orci consectetur tortor, id eleifend dolor sapien ut augue.
        </Tab>
  	    <Tab title="Fourth Tab">
            Aenean varius dui eget ante finibus, sit amet finibus nisi facilisis. Nunc pellentesque, risus et pretium hendrerit.
        </Tab>
    </Tabs>
</template>

就像这样,我们有可以在任何地方使用的标签。您可以查看下面的演示:

结论和源代码#

实现 Vue 选项卡非常简单,通过将这两个组件导入任何项目,您将立即拥有功能性选项卡。您可以通过此链接在 GitHub 上找到 Vue Tabs 的源代码

我希望你喜欢这个指南。如果你想要更多,你可以在这里找到我的其他 Vue 教程和指南