使用Vue实现Tabs组件(一)

前言

组件毫无疑问在Vue中是无比重要的,一个页面就是由各个组件组成,可以说是面向组件开发了。博主使用Vue也有一段时间了,工作中也封装过一些简单组件,但从未有一篇详细的文章记录下整个思想过程。于是就想写下该文章记录一个Tabs组件的封装。

准备工作

封装Tabs组件我这里先从最底层做起,先用 Html + JQuery 实现了一遍,然后根据已经实现的去进行拆分。

略过此步可以直接看使用Vue开发Tabs组件(二)

基本的Html代码为:

<div class="tab">
    <div class="tab-header">
        <ul class="tab-item">
            <li class="tab-item-title active">
                <a href="#">Tab1</a>
            </li>
            <li class="tab-item-title">
                <a href="#">Tab2</a>
            </li>
            <li class="tab-item-title">
                <a href="#">Tab3</a>
            </li>
            <div class="clear"></div>
        </ul>
    </div>
    <div class="tab-panel">
        <div class="tab-panel-content active">
            <h1>我的第一个标题</h1>

            <p>我的第一个段落。</p>
        </div>
        <div class="tab-panel-content">
            <h1>我的第二个标题</h1>

            <p>我的第二个段落。</p>
        </div>
        <div class="tab-panel-content">
            <h1>我的第三个标题</h1>

            <p>我的第三个段落。</p>
        </div>
    </div>
</div>

这里头部 Tab 使用 ul li 标签去实现,并且里面使用 a 标签去包裹着标题,方便之后事件操作使用。

css代码

html,
body {
    height: 100%;
    padding: 0;
    margin: 0;
}

a {
    text-decoration: none;
}

a:visited {
    color: #000;
}

.clear {
    clear: both;
}

.tab-item {
    list-style: none;
    padding-inline-start: 0;
}

.tab-item>.tab-item-title {
    position: relative;
    float: left;
    padding: 10px 15px;
    text-align: center;
    font-weight: 500;
    color: #000;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol';
}

.tab-item>.tab-item-title.active {
    color: #1890ff;
}

.tab-item>.tab-item-title.active::before {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 100%;
    transition: width .2s;
    background: #1890ff;
}

.tab-item>.tab-item-title::before {
    content: '';
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    width: 0;
}

.tab-item>.tab-item-title.active>a {
    color: #1890ff;
}

.tab-panel {
    display: flex;
    overflow: hidden;
    padding: 0 15px;
}

.tab-panel-content {
    height: 0;
    padding: 0 !important;
    overflow: hidden;
    opacity: 0;
    pointer-events: none;
    flex-shrink: 0;
    width: 0;
    -webkit-transition: opacity .45s;
    transition: opacity .45s;
}

.tab-panel-content.active {
    height: auto;
    opacity: 1;
    width: 100%;
}

js代码为

(function () {

    var Tab = function () {
        this._$tabItem = $('.tab-item').find('.tab-item-title');
        this._$tabPanel = $('.tab-panel').find('.tab-panel-content');
        this._selectIndex = 0;
        return this.init();
    }
    Tab.prototype = {
        changeTab: function (index) {
            this._$tabItem.removeClass('active');
            this._$tabPanel.removeClass('active')
            this._$tabItem.eq(index).addClass('active');
            this._$tabPanel.eq(index).addClass('active')
        },
        selectedIndex() {
            return this._selectIndex;
        },
        init: function () {
            var _this = this;
            this._$tabItem.click(function () {
                _this.changeTab($(this).index());
                _this._selectIndex = $(this).index();
            });
            return _this;
        }
    }
    var tab = new Tab();
})()

呈现效果
]]

以上就是基本的 Tab 组件 Html + JQuery的基本实现,很简单的一个实现,接下来就要使用Vue去进行改写。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的自定义tabs组件实现示例: ```vue <template> <div class="tabs"> <div class="tab-header"> <div v-for="(tab, index) in tabs" :key="index" :class="{ active: currentIndex === index }" @click="changeTab(index)" > {{ tab.title }} </div> </div> <div class="tab-content"> <slot /> </div> </div> </template> <script> export default { name: "Tabs", props: { defaultIndex: { type: Number, default: 0, }, }, data() { return { currentIndex: this.defaultIndex, tabs: [], }; }, methods: { changeTab(index) { this.currentIndex = index; }, registerTab(tab) { this.tabs.push(tab); }, }, mounted() { this.tabs = this.$children; }, }; </script> ``` 在这个组件中,我们使用了两个插槽,一个是tab-header用于显示标签页标题,另一个是tab-content用于显示标签页内容。组件内部维护了一个tabs数组,用于存储所有的标签页组件。 标签页组件实现如下: ```vue <template> <div v-show="active"> <slot></slot> </div> </template> <script> export default { name: "Tab", props: { title: { type: String, required: true, }, }, data() { return { active: false, }; }, mounted() { this.$parent.registerTab(this); }, updated() { if (this.$parent.currentIndex === this.$parent.tabs.indexOf(this)) { this.active = true; } else { this.active = false; } }, }; </script> ``` 在标签页组件中,我们维护了一个active属性,用于控制标签页是否显示。同时,当标签页组件的父组件Tabs更新时,我们会根据当前标签页在tabs数组中的位置和父组件当前激活的标签页的位置来更新active属性。 使用方式如下: ```vue <template> <div> <tabs> <tab title="Tab 1"> <p>Content of Tab 1</p> </tab> <tab title="Tab 2"> <p>Content of Tab 2</p> </tab> <tab title="Tab 3"> <p>Content of Tab 3</p> </tab> </tabs> </div> </template> <script> import Tabs from "@/components/Tabs.vue"; import Tab from "@/components/Tab.vue"; export default { name: "App", components: { Tabs, Tab, }, }; </script> ``` 其中,Tabs组件包含了三个Tab组件,每个Tab组件都有一个标题和内容。可以根据需要自行修改样式和内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值