效果预.jpg"alt="vue如何在tab标签页循环加定时器(v" />
当前位置:编程学习 > > 正文

vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)

时间:2022-03-30 14:37:54类别:编程学习

vue如何在tab标签页循环加定时器

vue实现tab标签标签超出自动滚动

当创建的tab标签超出页面可视区域时自动滚动一个tab标签距离,并可手动点击滚动tab标签,实现效果请.jpg" alt="vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)" border="0" />

效果预.jpg" alt="vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)" border="0" />

vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)

  • <template>
        <li class="main-box">
            <button @click="add">添加</button>
            <li class="main-box-tab">
                <i @click="previous"><<</i>
                <i @click="next">>></i>
                <li class="main-box-tab-content" ref="tabs">
                    <li class="main-box-tab-roll">
                        <li v-for="(item,index) in tabs" :key="index"
                             :class="{'tab-item-action':actionName === item.name ,'tab-item':actionName !== item.name}"
                             @click.stop="clickTab(item.name,index)">
                            <span>{{item.meta.title}}</span>
                            <i class="el-icon-close" @click.stop="close(item.name)"></i>
                        </li>
                    </li>
                </li>
            </li>
            <li class="main-box-content">
                <li>{{actionName}}</li>
            </li>
        </li>
    </template>
    <script>
        export default {
            name: "index",
            data() {
                return {
                    tabs: [],
                    moveX: 0,
                    count: 1,
                    unoccupied: 0,
                    tabsCount: 0,
                    actionName: 'test1'
                }
            },
            watch: {
                actionName(val) {
                    let len = this.tabs.length
                    // 如有重复数据退出后续函数执行
                    for (let i = 0; i < len; i++) {
                        if (this.tabs[i].name === val) {
                            this.$nextTick(() => {
                                this.translateX((i + 1 - this.tabsCount) * this.width - this.unoccupied)
                            })
                            return
                        }
                    }
    
                    this.tabs.push({
                        name: `test${this.count}`,
                        meta: {
                            title: `test${this.count}`
                        }
                    })
                    this.$nextTick(() => {
                      // (总共有多少个tabs - 未偏移时可见的元素个数) * 单个tab标签元素长度 - 被遮挡tab元素的可见部分的宽度
                        this.translateX((this.tabs.length - this.tabsCount) * this.width - this.unoccupied)
                    })
                }
            },
            mounted() {
                this.tabs.push({
                    name: `test${this.count}`,
                    meta: {
                        title: `test${this.count}`
                    }
                })
                this.$nextTick(() => {
                    let tabs = this.$refs.tabs
                    let getStyle = getComputedStyle(tabs.children[0].children[0], null)
                    let marginLeft = parseFloat(getStyle.marginLeft.substr(0, getStyle.marginLeft.length - 2))
                    let marginRight = parseFloat(getStyle.marginRight.substr(0, getStyle.marginRight.length - 2))
                    // 元素实际宽度 = 元素的宽度 + 外边距
                    this.width = marginLeft + marginRight + tabs.children[0].children[0].offsetWidth
    
                    /**
                     * 以下注释计算方式用于理解实现逻辑
                     **/
                    // // 可视区域能放入多少个元素 = 可视区域的宽度 / 子元素实际宽度
                    // let num = tabs.offsetWidth / this.width
    
                    // // 被遮挡tab元素的可见部分的宽度 = 可见区域的宽度 - (子元素实际宽度 * num转为整数)
                    // this.unoccupied = tabs.offsetWidth - (this.width * parseInt(num))
    
                    // 最终精简为取余(得数跟上面的计算是一样的)
                    this.unoccupied = tabs.offsetWidth % this.width
                    // 转为整数
                    this.tabsCount = parseInt(tabs.offsetWidth / this.width)
                })
            },
            methods: {
                add() {
                    this.count++
                    this.actionName = `test${this.count}`
                },
    
                /**
                 * 切换tab标签页
                 **/
                clickTab(name) {
                    if (this.actionName !== name) {
                        this.actionName = name
                    }
                },
    
                /**
                 * 关闭tab标签页
                 **/
                close(name) {
                    let len = this.tabs.length
                    let jumpName = null
                    if (len > 1) {
                        for (let i = 0; i < len; i++) {
                            if (this.tabs[i].name === name) {
                                this.tabs.splice(i, 1)
    
                                jumpName = this.tabs[i ? i - 1 : 0].name
                                if (this.actionName !== jumpName && name === this.actionName) {
                                    this.actionName = jumpName
                                }
    
                                this.$nextTick(() => {
                                    this.previous()
                                })
                                return
                            }
                        }
                    }
                },
    
                /**
                 * 往右偏移
                 **/
                next() {
                    // scrollWidth获取不准确
                    // 使用this.width * this.tabs.length计算出总长度
                    let totalWidth = this.width * this.tabs.length
    
                    this.$nextTick(() => {
                        let dom = this.$refs.tabs
                        // 可视区域 < 滚动区域(滚动区域大于可视区域才可以移动)
                        // 移动距离 + 可视区域 = 滚动区域的宽度(上一次的宽度,当点击时才是实际宽度)< 滚动区域
                        if (dom.clientWidth < totalWidth && this.moveX + dom.clientWidth < totalWidth) {
                            // this.moveX为0减去空余空间的宽度
                            this.moveX += this.moveX ? this.width : this.width - this.unoccupied
                            this.translateX(this.moveX)
                        }
                    })
                },
    
                /**
                 * 往左偏移
                 **/
                previous() {
                    if (this.moveX > 0) {
                        this.moveX -= this.width
                        this.translateX(this.moveX)
                    }
                },
    
                /**
                 * 开始移动dom
                 **/
                translateX(x) {
                    this.moveX = x < 0 ? 0 : x
                    this.$refs.tabs.children[0].style.transform = `translateX(-${this.moveX}px)`
                }
            }
        }
    </script>
    
    <style lang="scss" scoped>
        .main-box {
            height: 500px;
            width: 500px;
            padding: 10px 20px 20px 20px;
    
            .main-box-tab {
                position: relative;
                padding: 10px 20px;
                overflow: hidden;
    
                & > i {
                    position: absolute;
                    cursor: pointer;
                    bottom: 15px;
    
                    &:nth-child(1) {
                        left: 0;
                    }
    
                    &:nth-child(2) {
                        right: 0;
                    }
                }
    
                .main-box-tab-content {
                    overflow: hidden;
    
                    .main-box-tab-roll {
                        transition: transform .5s;
                        display: flex;
                        align-items: center;
    
                        li {
                            flex-shrink: 0;
                            cursor: pointer;
                            width: 130px;
                            height: 25px;
                            margin: 0 5px;
                            display: flex;
                            align-items: center;
                            justify-content: space-between;
    
                            span, i {
                                font-size: 12px;
                            }
    
                            span {
                                margin-left: 10px;
                                overflow: hidden;
                                white-space: nowrap;
                                text-overflow: ellipsis;
                            }
    
                            i {
                                margin-right: 10px;
                            }
                        }
                    }
                }
    
                .tab-item {
                    color: #cccccc;
                    background-color: rgba(255, 255, 255, .5);
                    border-radius: 0 1px 0 1px;
                    border: 1px solid #052141;
                }
    
                .tab-item-action {
                    color: #ffffff;
                    background: rgba(0, 180, 255, 0.8);
                    border-radius: 0 1px 0 1px;
                    border: 1px solid #1E2088;
                }
    
            }
    
            .main-box-content {
                height: calc(100% - 70px);
                padding: 10px;
                border: 1px saddlebrown solid;
                background-size: 100% 100%;
            }
        }
    </style>
    
  • 到此这篇关于vue实现tab标签(标签超出自动滚动)的文章就介绍到这了,更多相关vue tab标签 内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!

    标签:
    上一篇下一篇

    猜您喜欢

    热门推荐