《vue.js实战》练习---标签页组件

html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="style.css">
    <title>Title</title>
</head>
<body>
    <div id="app">
        <tabs v-model="activeKey">
            <pane label="图片">
                我是图片内容...
            </pane>
            <pane label="视频">
                我是视频内容...
            </pane>
            <pane label="音乐">
                我是音乐内容...
            </pane>
            <pane label="文章">
                我是文章内容...
            </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>
        var app = new Vue({
            el: '#app',
            data: {
                activeKey: '0'
            }
        })
    </script>
</body>
</html>

 

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: #ffffff;
    border: 1px solid #d7dde4;
    cursor: pointer;
    position: relative;
}

.tabs-tab-active {
    color: #3399ff;
    border-top: 1px solid #3399ff;
    border-bottom: 1px solid #ffffff;
}

.tabs-tab-active:before {
    content: '';
    display: block;
    height: 1px;
    background: #3399ff;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
}

.tabs-content {
    padding: 8px 0;
}

 

pane.js:

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

 

tabs.js:

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

            })
        },
        handleChange: function (index) {
            this.currentValue = index;
            this.$emit('input',index);
        }
    },
    watch: {
        currentValue: function () {
            this.updateStatus();
        },
        value: function (val) {
            this.currentValue = val;
        }
    }
})

 

效果图:

 

posted @ 2018-06-25 14:55  asimpleday  阅读(612)  评论(0编辑  收藏  举报