美文网首页爱编程
Vue: 标签页组件

Vue: 标签页组件

作者: 一叶扁舟丶 | 来源:发表于2018-10-23 19:48 被阅读1次

    index.html:

    
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>标签页组件</title>
        <link rel="stylesheet" type="text/css" href="style.css">
    
    </head>
    <body>
        <div id="app" v-cloak>
            <tabs v-model="activeKey">
                <pane label="标签一" name="1">
                    标签一的内容
                </pane>
                <pane label="标签二" name="2">
                    标签二的内容
                </pane>
                <pane label="标签三" name="3">
                    标签三的内容
                </pane>
            </tabs>
        </div>
        
        <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
        <script src="pane.js"></script>
        <script src="tabs.js"></script>
        <script type="text/javascript">
            var app = new Vue({
                el: '#app',
                data: {
                    activeKey: '1'
                }
            })
        </script>
    
    
    </body>
    </html>
    

    pane.js:

    Vue.component('pane', {
       name: 'pane',
       template: '\
           <div class="pane" v-show="show">\
               <slot></slot>\
           </div>',
       props: {
           name: {
               type: String
           },
           label: {
               type: String,
               default: ''
           }
       },
       data: function () {
           return {
               show: true
           }
       },
       methods: {
           updateNav () {
               this.$parent.updateNav();
           }
       },
       watch: {
           label () {
               this.updateNav();
           }
       },
       mounted () {
           this.updateNav();
       }
    })
    

    tabs.js:

    Vue.component('tabs', {
        template: '\
            <div class="tabs">\
                <div class="tabs-bar">\
                    <div \
                        :class="tabCls(item)"\
                        v-for="(item, index) in navList"\
                        @click="handleChange(index)">\
                        {{ item.label }}\
                    </div>\
                </div>\
                <div class="tabs-content">\
                    <slot></slot>\
                </div>',
        props: {
            value: {
                type: [String, Number]
            }
        },
        data: function () {
            return {
                currentValue: this.value,
                navList: []
            }
        },
        methods: {
            tabCls: function (item) {
                return [
                    'tabs-tab',
                    {
                        'tabs-tab-active': item.name === this.currentValue
                    }
                ]
            },
            getTabs () {
                return this.$children.filter(function (item) {
                    return item.$options.name === 'pane';
                });
            },
            updateNav () {
                this.navList = [];
                var _this = this;
    
                this.getTabs().forEach(function (pane, index) {
                    _this.navList.push({
                        label: pane.label,
                        name: pane.name || index
                    });
                    if (!pane.name) pane.name = index;
                    if (index === 0) {
                        if (!_this.currentValue) {
                            _this.currentValue = pane.name || index;
                        }
                    }
                });
    
                this.updateStatus();
            },
            updateStatus () {
                var tabs = this.getTabs();
                var _this = this;
    
                tabs.forEach(function (tab) {
                    return tab.show = tab.name === _this.currentValue;
                })
            },
            handleChange: function (index) {
                var nav = this.navList[index];
                var name = nav.name;
                this.currentValue = name;
                this.$emit('input', name);
                this.$emit('on-click', name);
            }
        },
        watch: {
            value: function (val) {
                this.currentValue = val;
            },
            currentValue: function () {
                this.updateStatus();
            }
        }
    
    })
    

    style.css:

    [v-cloak] {
        display: none;
    }
    .tabs {
        font-size: 14px;
        color: #657180;
    }
    .tabs-bar:after{
        content: '';
        display: block;
        width: 100%;
        height: 1px;
        background: #d7dde4;
        margin-top: -1px;
    }
    .tabs-tab {
        display: inline-block;
        padding: 4px 16px;
        margin-right: 6px;
        background: #fff;
        border: 1px solid #d7dde4;
        cursor: pointer;;
        position: relative;
    }
    .tabs-tab-active {
        color: #3399ff;
        border-top: 1px solid #3399ff;
        border-bottom: 1px solid #fff;
    }
    .tabs-tab-active:before{
        content: '';
        display: block;;
        height: 1px;
        background: #3399ff;
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
    }
    .tabs-content {
        padding: 8px 0;
    }
    

    相关文章

      网友评论

        本文标题:Vue: 标签页组件

        本文链接:https://www.haomeiwen.com/subject/djtzzftx.html