可重用的组件在 VueJS 中非常重要。它可以帮助您节省大量时间,并且如果做得正确,确实可以使您的项目更具可读性和可维护性。
在本教程中,我们将制作一个自定义选项卡组件,允许将任何类型的内容转换为单页选项卡系统。
这就是我们要做的!
希望本教程能让您深入了解设计可重用组件。另外,您还将获得一些有用的 Vue 代码!
免责声明:本教程假设您对 VueJS 有一点了解,如果您想了解更多基础知识,我建议从我的其他一些教程开始。
可重用组件简介 {#introduction-to-reusable-components}
开发人员喜欢使用的关键词之一是"不要重复自己" (DRY)。在 VueJS 中,可重用代码在很多情况下都很有用:滚动功能、标题组件,或者在我们的例子中,创建选项卡系统。
有多种方法可以实现可重用代码。一种常见的方法是使用mixins来提取功能,另一种方法是使用插槽来提供定制和灵活性。
对于我们的选项卡系统,我们将使用插槽,以便我们可以在每个选项卡中放置我们想要的任何类型的内容。
好的------让我们开始编码。
一切准备就绪 {#getting-all-set-up}
我们的选项卡系统只需要两个组件即可工作,然后另一个组件来测试我们的新项目。对于功能,我们需要:
-
Tab.vue -- 可以显示的每个单独的内容选项卡
-
Tabs.vue -- 包含所有选项卡和显示它们的句柄。
这个想法非常简单。Tabs.vue 组件将是一个包含单个槽的包装器。然后,当我们创建 Tabs 元素时,我们为每个不同的内容片段传递几个单独的 Tab.vue 组件。
为了使示例代码尽可能轻量,我们使用全局 vue-cli 来帮助构建所有内容。因此,要运行实际的项目,首先我们需要安装npm install -g @vue/cli-service-global
,然后我们就可以使用vue serve src/Demo.vue
来实际运行项目。
让我们先了解基本功能,然后我们可以通过更多样式使其变得更奇特。
设置可重用选项卡组件 {#setting-up-a-reusable-tab-component}
Tab.vue
是我们选项卡系统中最里面的组件,也是最简单设置的组件之一。
我们真正想做的就是获取一些识别数据(选项卡标题),并根据布尔值显示某种内容。title
我们将作为组件属性传递并存储isActive
为数据值,以便我们可以从另一个组件控制它。
为了允许我们在选项卡中显示任何类型的内容,我们可以使用slot。
这个组件非常简单,所以我只向您展示代码。
为了允许我们在选项卡中显示任何类型的内容,我们可以使用slot。
<template>
<div v-show="isActive">
<slot></slot>
</div>
</template>
<script>
export default {
props: {
title: {
type: String,
default: 'Tab'
}
},
data () {
return {
isActive: true
}
}
}
</script>
我们使用 Vue 的原因v-show
之一v-if
是实现 Vue 具有的一些保持活动功能。
我们稍后会返回并为此组件添加更多自定义选项,但这足以帮助您入门。
设置选项卡包装组件 {#setting-up-the-tabs-wrapper-component}
现在,让我们创建一些框架代码,以使其能够处理各种选项卡。Tabs.vue
首先,我认为我们应该确定该组件的 JavaScript 代码。
让我们从定义数据选项开始------我们需要一个 Tab.vue 组件数组和一个索引来跟踪当前选择的选项卡。那应该看起来像这样。
<script>
export default {
data () {
return {
selectedIndex: 0 // the index of the selected tab,
tabs: [], // all of the tabs
}
}
}
</script>
接下来,我们实际上应该弄清楚如何在选项卡中加载。该组件实际与插槽一起使用的方式如下所示。
<!-- THIS IS JUST A SIMPLIFIED EXAMPLE. ITLL LOOK A LITTLE DIFFERENT -->
<tabs>
<tab>Tab 1</tab>
<tab>Tab 2</tab>
<tab>Tab 3</tab>
<tab>Tab 4</tab>
</tabs>
正如您所看到的,每个选项卡都是Tabs.vue 组件的子级- 这意味着我们可以使用一些 VueJS 和普通 JavaScript 模式来获取所有子级。
这段代码很简单,我们把它扔到created生命周期钩子里就可以了。
<script>
export default {
data () {
return {
selectedIndex: 0 // the index of the selected tab,
tabs: [], // all of the tabs
}
},
created () {
this.tabs = this.$children
}
}
</script>
现在,我们的 tabs 变量将拥有一堆我们可以迭代的 Vue 组件对象。
该Tabs.vue
组件将包含所有单独的选项卡,但为了使其尽可能灵活,我们将使用一个插槽,以便我们可以使用任意数量的选项卡。
现在,我们的组件代码将如下所示。
<template>
<div>
<ul class="tabs__header">
<li v-for="tab in tabs" :key="tab.title">{{ tab.title }}</li>
</ul>
<slot></slot>
</div>
</template>
<script>
export default {
data () {
return {
selectedIndex: 0, // the index of the selected tab,
tabs: [] // all of the tabs
}
},
created () {
this.tabs = this.$children
}
}
</script>
制作演示页面 {#making-a-demo-page}
接下来,我们需要某种组件来测试选项卡组件,看看一切是否设置正确。
因此,在我们的Demo.vue
组件中,我们必须导入 Tab 和 Tabs 组件,然后创建一些示例元素。
这非常简单;对于这个例子,这是我使用的代码。
<template>
<div>
<tabs>
<tab title="Tab 1">Hello From Tab 1</tab>
<tab title="Tab 2">Hello From Tab 2</tab>
<tab title="Tab 3">Hello From Tab 3</tab>
<tab title="Tab 4">Hello From Tab 4</tab>
</tabs>
</div>
</template>
<script>
import Tab from './Tab.vue'
import Tabs from './Tabs.vue'
export default {
components: {
Tab,
Tabs
}
}
</script>
现在我们已经将所有组件连接起来了!让我们尝试一下。如果您之前错过了它,请确保安装了 @vue/cli-service-global -- 然后我们可以从命令行运行它。导航到项目的根文件夹并运行vue serve src/Demo.vue
如果您包含与我相同的内容,您应该会看到类似这样的内容。
我知道。现在它非常基本,根本没有选项卡内容,但不用担心,我们即将添加所有功能。
添加选项卡功能 {#adding-the-tab-functionality}
现在我们已经设置了所需的所有组件并准备就绪,让我们开始实际添加选项卡部分。
这实际上很简单。我们必须编辑该Tabs.vue
文件。首先,我们将添加一个方法来选择要显示的选项卡。添加以下 JavaScript:
<script>
mounted () {
this.selectTab(0)
},
methods: {
selectTab (i) {
this.selectedIndex = i
// loop over all the tabs
this.tabs.forEach((tab, index) => {
tab.isActive = (index === i)
})
}
}
</script>
这使得一次只有一个选项卡可见,并且也使得在选项卡之间切换变得非常容易。现在,要使用标题控制哪个选项卡可见,我们可以使用 VueJS 单击事件。
我们只需更改标题代码即可在单击列表项之一时调用我们的新方法。我们的新代码应该如下所示。
<li v-for="(tab, index) in tabs" :key="tab.title" @click="selectTab(index)">
{{ tab.title }}
</li>
现在,我们应该有一个工作选项卡系统,其中内容会对我们的点击做出反应。
那里!我们有一个工作标签系统!
每个选项卡都可以包含任何类型的内容:文本、图像、表单,甚至其他自定义组件。这种灵活性使得该组件极具可重用性。但显然,它需要视觉升级。
让它看起来更好 {#making-it-look-better}
由于本文的重点是 VueJS 组件,而不是大量的 CSS 编程,因此我不会详细介绍该元素的 CSS。但您可以随时访问本教程的存储库并四处查看。
我要解释一下的一件事是如何让所选选项卡以某种样式显示。为此,我们可以使用 v-bind 来绑定类属性。在 Vue 中,这需要一个对象,其中有类名和用于切换类的布尔值。
对于这种情况,我们必须编辑 Tabs.vue 中的标题,它看起来像这样......
<li
v-for="(tab, index) in tabs"
:key="tab.title"
@click="selectTab(index)"
:class='{"tabs__selected": (index == selectedIndex)}'
>
{{ tab.title }}
</li>
这意味着当索引等于所选索引时(我们位于所选选项卡上),该元素将具有 .tabs__selected 类。这允许我们向选定的选项卡添加一些自定义样式。
总而言之,在花了一点时间把一切变得漂亮之后。这就是我们的选项卡组件的样子。
如果您希望自己的代码看起来像这样,只需从 GitHub 复制代码[https://github.com/matthewmaribojoc/learn-vue-tab]即可。
使其更加可定制的一种超级简单的方法是添加几种可以通过道具切换的不同样式。您确实可以添加任何您想要的功能:图标点、颜色变量等。
现在,我将展示一个示例,我们可以使用道具在多种样式之间切换。在我们的例子中,我们将有一个浅色模式和一个深色模式。
为此,我们必须在 Tabs.vue 文件中添加一个 prop。只需将以下代码添加到您的导出默认值中即可。
<script>
export default {
props: {
mode: {
type: String,
default: 'light'
}
}
}
</script>
然后,我们可以使用与添加所选选项卡类相同的技术向 Tabs.vue 根元素添加一个类。在这种情况下,我们需要有两个可切换的类,一个用于浅色,一个用于深色。(以及您想要的任何其他样式)
<div
:class='{"tabs__light": mode === "light", "tabs__dark": mode === "dark"}'
></div>
接下来,要添加实际实现的自定义样式,我们只需调整现有的 CSS 选择器并添加一些新的选择器即可为每种模式提供元素样式。再次,只需查看存储库[https://github.com/matthewmaribojoc/learn-vue-tab]以获取最终代码。
最后,我们必须更新Demo.vue
以将模式属性传递给我们的组件。出于演示目的,我制作了一个在两种样式之间切换的按钮。这就是更新后的 Demo 组件的样子
<template>
<div>
<button @click="changeStyle()">Change Style</button>
<tabs :mode="mode">
<tab title="Tab 1">Hello From Tab 1</tab>
<tab title="Tab 2">Hello From Tab 2</tab>
<tab title="Tab 3">Hello From Tab 3</tab>
<tab title="Tab 4">Hello From Tab 4</tab>
</tabs>
</div>
</template>
<script>
import Tab from './Tab.vue'
import Tabs from './Tabs.vue'
export default {
components: {
Tab,
Tabs
},
data () {
return {
mode: 'dark'
}
},
methods: {
changeStyle () {
if (this.mode === 'dark') {
this.mode = 'light'
} else {
this.mode = 'dark'
}
}
}
}
</script>
现在,这就是我们的网站的样子......
这只是添加自定义道具的冰山一角。这实际上取决于您希望如何将此选项卡系统扩展到您的 Vue 项目中。当然只是尝试一下,看看有什么可能!
可重用组件的关键要点 {#key-takeaways-for-reusable-components}
希望您能够了解一些有关使用槽来设计可重用组件的知识。
这是避免重复代码的好方法,也是包含您想要的任何类型内容的超级灵活方法。
请记住,在开始编程之前,您应该始终计划好 props/data和继承。我知道这样做很乏味,但是当您忘记哪个组件可以访问哪些数据时,它会为您省去很多麻烦。