数据大屏开发中,需要实现一个步骤条的效果,但是步骤条的长度可能会很大超过了当前显示区域,所以我们需要一个可以鼠标横向拖动的效果。
动态拖动效果
开发环境
vue2 webpack js
使用插件
"@better-scroll/core": "^2.5.1",
实现代码及封装
/**
* @Author: 858834013@qq.com
* @Name: scrollbar
* @Date: 2023年10月17日11:23:43
* @Desc: 横向拖动滚动
*/
<template>
<div class="tabsBody horizontal-scrollbar-container">
<div class="tabs scroll-wrapper" ref="scroll">
<div class="scroll-content" ref="scroll2">
<div class="steps">
<div class="stepsLine"></div>
<div class="stepsItem" :class="{active:active>=index}" v-for="(item,index) in list" :key="index">
<div class="line"></div>
<div class="stepsItemInner">
<img v-if="active>=index" src="./assets/icon_1.png" alt="">
<img v-else src="./assets/icon_2.png" alt="">
<div class="stepTitle">{{ item.title }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import BScroll from '@better-scroll/core'
export default {
name: 'tabs',
components: {
},
data() {
return {
index: 0,
scroll: null,
lastSpot: 0
}
},
props: {
list: {
type: Array,
default() {
return []
}
},
active: {
type: Number,
default() {
return 0
}
},
},
mounted() {
var that = this
that.$nextTick(() => {
that.init2()
})
},
watch: {
list() {
var that = this
that.$nextTick(() => {
that.init2()
})
}
},
methods: {
init2() {
var that = this
this.scroll = new BScroll(this.$refs.scroll, {
scrollX: true,
scrollY: false,
click: true,
probeType: 1,
scrollbar: {
fade: true,
interactive: false,
scrollbarTrackClickable: false,
scrollbarTrackOffsetType: 'clickedPoint' // can use 'step'
}
})
this.scroll.on('scrollEnd', (e) => {
console.log('scrollEnd')
this.lastSpot = Math.abs(e.x)
})
this.scroll.on('scrollStart', (e) => {
console.log('scrollStart')
console.log(e)
})
this.scroll.on('scroll', () => {
console.log('scroll')
})
}
}
}
</script>
<style lang="scss" scoped>
.tabsBody {
width: 100%;
overflow: hidden;
position: relative;
height: 100%;
}
.newTabs {
display: flex;
display: -webkit-flex;
padding: 0;
position: relative;
height: 100%;
}
.tab2 {
width: 200px;
position: relative;
height: 100%;
//background: red;
}
.steps {
width: auto;
display: flex;
overflow: hidden;
justify-content: flex-start;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
position: relative;
.stepsItem {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
position: relative;
flex-shrink: 0;
z-index: 1;
margin-right: 30px;
.line {
position: absolute;
left: -90%;
width: 120%;
height: 1px;
background: #435797;
top: 9px;
}
&:last-child {
margin-right: 20px;
}
}
.stepsItemInner {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: column;
align-content: flex-start;
.stepNum {
display: flex;
justify-content: center;
align-items: center;
flex-wrap: nowrap;
flex-direction: row;
align-content: flex-start;
border-radius: 50%;
font-size: 20px;
font-family: MicrosoftYaHei;
color: rgba(176, 230, 255, 1);
}
.stepTitle {
font-size: 12px;
font-family: PingFang;
font-weight: 500;
color: rgba(176, 230, 255, 1);
width: 50px;
text-align: center;
margin-top: 5px;
}
}
.stepsItem.active {
.line {
background: #00cde7;
}
.stepsItemInner {
.stepNum {
background: #00cde7;
color: #FFFFFF;
}
.stepTitle {
color: #fff;
}
}
}
}
.stepsLine {
width: 90%;
height: 1px;
top: 9px;
background: rgba(77, 98, 163, 1);
position: absolute;
}
.scroll-content {
display: inline-block;
align-self: center;
position: relative;
height: 100%;
}
</style>
使用组件
<steps :list="stepsList" :active="stepsActive"></steps>
stepsActive: 3,
stepsList: [{
title: '无为市人'
}, {
title: '无为市人民'
}, {
title: '无为市人'
}, {
title: '无为市人'
}, {
title: '无为市人'
}, {
title: '无为市人'
}, {
title: '无为市人'
}]