vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)
vue如何在tab标签页循环加定时器
vue实现tab标签标签超出自动滚动当创建的tab标签超出页面可视区域时自动滚动一个tab标签距离,并可手动点击滚动tab标签,实现效果请.jpg" alt="vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)" border="0" />
效果预.jpg" alt="vue如何在tab标签页循环加定时器(vue实现tab标签标签超出自动滚动)" border="0" />
<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标签 内容请搜索开心学习网以前的文章或继续浏览下面的相关文章希望大家以后多多支持开心学习网!
- vue编程加入购物车(vuex实现简单的购物车功能)
- vue3封装table组件(Vue封装通用table组件的完整步骤记录)
- vueweb端聊天(Vue实现聊天界面)
- vue原理详解(vue响应式原理与双向数据的深入解析)
- vue动态列表布局(vue项目实现左滑删除功能完整代码)
- vue-cli安装教程学习(Vue新手指南之创建第一个vue-cli脚手架程序)
- vue如何检查数组变化(Vue2中无法检测到数组变动的原因及解决)
- vue本地图片切换(vue动态加载本地图片的处理方法)
- vue路由有几种实现模式(Vue实现路由过渡动效的4种方法)
- vue项目打包上线的方法(vue项目打包以及优化的实现步骤)
- vue3 ref 的用法(Vue3中watchEffect的用途浅析)
- vue怎么注册公共组件(解读Vue组件注册方式)
- vue使用elementui框架(总结Vue Element UI使用中遇到的问题)
- vue element admin接口(Vue-Element-Admin集成自己的接口实现登录跳转)
- vue3.0路线图(Vue3.0 自己实现放大镜效果案例讲解)
- vue界面自动生成(Vue中实现3D标签云的详细代码)
- 小敏家 剧情离谱一锅乱炖,但他们俩绝对是这部剧的一大 亮点(剧情离谱一锅乱炖)
- 《倚天屠龙记》再遭翻拍,关晓彤主演赵敏,蒋劲夫演张无忌,你怎么看(倚天屠龙记再遭翻拍)
- 吴启华与曾舜晞两代张无忌同框,戏里经典的他却没活出原著的潇洒(吴启华与曾舜晞两代张无忌同框)
- 经常发这三种 朋友圈 的人,要迅速屏蔽(经常发这三种朋友圈)
- 有种尴尬叫朋友圈忘屏蔽,大学生上演社死现场,父母亲自下场吐槽(有种尴尬叫朋友圈忘屏蔽)
- 朋友圈屏蔽你的人,可以直接看淡了(朋友圈屏蔽你的人)
热门推荐
- php实现导航地图(php根据地址获取百度地图经纬度的实例方法)
- php考试复习题(php+mysql开发的最简单在线题库在线做题系统完整案例)
- python读取文件的正确方法(强悍的Python读取大文件的解决方案)
- tomcat处理乱码(Tomcat中catalina.bat设置为UTF-8控制台出现乱码)
- vue-router的安装(详解Vue-Router的安装与使用)
- dede网站地图模块(Dedecms中百度网站地图制作的方法图文教程)
- wampserver配置教程图文(WampServer安装配置及使用图文教程)
- css如何做出矩形三角流程效果(css做个波浪悬浮球的实现方法)
- html5 canvas绘图(使用html5 canvas绘制圆环动效)
- nginx与tomcat长连接(Windows下使用Nginx+Tomcat做负载均衡的完整步骤)
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9