vue中类tabs左右滑动
效果图
思路
给定一个变量用来记录滚动了几列,每滚动一次加1滚动一列,监听页面滚动父级元素宽度改变,重新设置滚动的距离(放在计算属性中让其自动计算)
<template>
<div class="container">
<el-button @click="prev">左滑</el-button>
<div class="box" ref="box">
<div
class="wrap"
ref="wrap"
:style="{ transform: `translateX(-${scrollX}px)` }"
>
<div
v-for="(item, index) in 8"
:key="index"
:style="{ width: widthItem + 'px' }"
:class="['item', 'item' + index]"
>
滚动{{ index }}
</div>
</div>
</div>
<el-button @click="next">右滑</el-button>
</div>
</template>
<script>
// 引入 npm install element-resize-detector --save
let elementResizeDetectorMaker = require("element-resize-detector");
export default {
props: {
// 显示几列
column: {
type: Number,
default: 5
}
},
data() {
return {
// 滚动了几列
roll: 0,
// 每一列的宽度
widthItem: 0,
// 盒子总宽度
widthBox: 0
};
},
computed: {
scrollX() {
// flex布局时计算宽度,某些情况下会出现小数点,对比宽度比总宽度小1,使右滑出问题
return Math.ceil(this.roll * this.widthItem);
}
},
mounted() {
let erd = elementResizeDetectorMaker();
let _this = this;
// 监听box元素宽度改变
erd.listenTo(this.$refs.box, function(element) {
_this.widthBox = element.offsetWidth;
// 计算每一列占多少行
_this.widthItem = element.offsetWidth / _this.column;
});
},
methods: {
next() {
let widthWrap = this.$refs.wrap.offsetWidth;
if (this.widthBox + this.scrollX >= widthWrap) return;
this.roll += 1;
},
prev() {
if (this.scrollX <= 0) return;
this.roll -= 1;
}
}
};
</script>
<style scoped lang="scss">
.container {
display: flex;
width: 100%;
height: 60px;
.box {
flex: 1;
border: 1px solid skyblue;
overflow: hidden;
.wrap {
display: inline-block;
white-space: nowrap;
transition: transform 0.3s;
.item {
display: inline-block;
height: 100%;
line-height: 60px;
text-align: center;
background-color: aquamarine;
}
}
}
}
</style>