美文网首页
《Vue.js实战》学习笔记-组件示例(二)

《Vue.js实战》学习笔记-组件示例(二)

作者: 863cda997e42 | 来源:发表于2020-04-28 16:21 被阅读0次

Vue.js实战

标签页组件

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>标签页组件</title>
    <script src="https://unpkg.com/vue/dist/vue.min.js"></script>
    <style>
        [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;
        }
    </style>
</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>
        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();
            }
        });
    </script>

    <script>
        Vue.component('tabs', {
            template: '\
                <div class="tabs">\
                    <div class="tabs-bar">\
                        <div \
                            v-for="(item, index) in navList"\
                            :class="tabCls(item)"\
                            @click="handleChange(index)">\
                            {{item.label}}\
                        </div>\
                    </div>\
                    <div class="tabs-content">\
                        <slot></slot>\
                    </div>\
                </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();
                }
            }
        });
    </script>

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

</body>

</html>

相关文章

网友评论

      本文标题:《Vue.js实战》学习笔记-组件示例(二)

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