<!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="标签1" name="1">
                标签1的内容
            </pane>
            <pane label="标签2" name="2">
                标签2的内容
            </pane>
            <pane label="标签3" name="3">
                标签3的内容
            </pane>
        </tabs>
    </div>
</body>

</html>

<script src="jquery-3.1.1.js"></script>
<script src="vue.js"></script>



<script>
    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: {
            lable() {
                this.updateNav();
            }
        },
        mounted() {
            this.updateNav();
        }
    });



    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>\
                </div>',

        props: {
            value: { //这里用于v-model绑定,好像只能用value,而不能用其他关键字; value 就是动态索引(指定哪一个标签处于活动状态)
                type: [String, Number]
            }
        },
        data: function() {
            return {
                currentValue: this.value,
                navList: []
            }
        },
        methods: {
            tabCls: function(item) {

                var temp_xx = [
                    'tabs-tab', {
                        'tabs-tab-active': item.name === this.currentValue
                    }
                ];

                //秘诀:将对象转为json字符串
                //动态类:["tabs-tab",{"tabs-tab-active":true}]
                temp_xx = JSON.stringify(temp_xx);
                console.log("动态类:" + temp_xx);
                return temp_xx;
            },
            getTabs() {
                return this.$children.filter(function(item) {
                    //console.log(item.$options);
                    //console.log('----------------------');
                    //返回标签的名字是“pane”的子孙
                    return item.$options.name === 'pane';
                });
            },
            updateNav() {
                this.navList = [];
                var _this = this;

                this.getTabs().forEach(function(pane, index) {
                    //console.log('lable:' + pane.label);
                    //console.log('name:' + pane.name);
                    //console.log('-----------');
                    _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();
                //console.log('符合条件的tabs-----------');
                //console.log(tabs);

                var _this = this;

                //每个标签是否显示,取决于它的变量"show";而变量“show”是否为“true”取决于它的name是否为currentValue
                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();
            }
        }
    });

    var app = new Vue({
        el: '#app',
        data: {
            activeKey: '1'
        }
    });
</script>

 

posted on 2019-09-10 09:10  qqhfeng16  阅读(262)  评论(0编辑  收藏  举报