具体代码如下
<template>
<div>
<div
class="ProgressBoxTool"
v-if="state.progressList && state.progressList.length"
>
<div class="processBox">
<div
:class="state.currentClickNumber > 0 ? 'arrow' : 'arrow arrowOpacity'"
@click="fnPrev()"
>
<img :src="arrowL" alt="" />
</div>
<div class="fixedBox" ref="fixedBox">
<div
class="centerScroll"
:style="`width:${
state.signleWidth * state.progressList.length
}px;transform:translate(${
state.scrollResultWidth
}px,0);transition:1s;`"
>
<div
class="signleTab"
v-for="(itemP, indexP) in state.progressList"
:key="indexP + 'progress'"
>
<div class="leftIcon">
<img class="pregressIcon" :src="icon" alt="" />
</div>
<!-- 最后一个不展示箭头 -->
<img
v-if="state.progressList.length > indexP + 1"
:src="iconArrow"
alt=""
class="arrowSquare"
/>
</div>
</div>
</div>
<div
:class="state.noScrollRight ? 'arrow' : 'arrow arrowOpacity'"
@click="fnNext()"
>
<img :src="arrowR" alt="" />
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { reactive, ref, onMounted } from "vue";
import arrowL from "../../assets/images/arrow.png";
import arrowR from "../../assets/images/arrow.png";
import icon from "../../assets/images/icon.png";
import iconArrow from "../../assets/images/arrow.png";
const state = reactive({
progressList: [
{ type: "1" },
{ type: "2" },
{ type: "1" },
{ type: "2" },
{ type: "1" },
{ type: "2" },
{ type: "1" },
{ type: "2" },
{ type: "1" },
{ type: "2" }
],
currentProgressId: "",
scrollResultWidth: 0, //transform滚动的距离
signleWidth: 215, //单个流程的宽度
activeName: 0,
currentClickNumber: 0,
noScrollRight: true
});
const fixedBox = ref();
const initgoRightArrow = () => {
const currentScrollWidth = fixedBox.value.clientWidth;
const canNumber = Math.floor(currentScrollWidth / state.signleWidth); //可以放下的个数
//如果最后一个流程图标已经展示出来,则停止滚动
if (state.currentClickNumber + canNumber >= state.progressList.length) {
state.noScrollRight = false;
return;
}
};
onMounted(() => {
initgoRightArrow();
});
const fnPrev = () => {
//如果右点击的次数大于0,才可以左滚
if (state.currentClickNumber > 0) {
state.currentClickNumber -= 1;
state.noScrollRight = true;
fnScrollWidth("reduce");
} else {
return false;
}
};
const fnNext = () => {
const currentScrollWidth = fixedBox.value.clientWidth;
const canNumber = Math.floor(currentScrollWidth / state.signleWidth); //可以放下的个数
//如果最后一个流程图标已经展示出来,则停止滚动
if (state.currentClickNumber + canNumber >= state.progressList.length) {
return;
}
//说明放不下有滚动条
if (state.progressList.length > canNumber) {
state.currentClickNumber += 1;
if (state.currentClickNumber + canNumber >= state.progressList.length) {
state.noScrollRight = false;
}
fnScrollWidth("add");
}
};
const fnScrollWidth = type => {
let result = 0;
if (type === "reduce") {
result = 215;
} else if (type === "add") {
result = -215;
} else {
result = 0;
}
state.scrollResultWidth += result;
};
</script>
<style lang="scss" scoped>
//中间的时间发展部分
.processBox {
display: flex;
align-items: center;
justify-content: space-between;
.arrow {
width: 60px;
cursor: pointer;
}
.arrowOpacity {
cursor: default;
opacity: 0.4;
}
.fixedBox {
flex: 1;
overflow: hidden;
}
.centerScroll {
// flex: 1;
box-sizing: border-box;
padding: 20px 0;
white-space: nowrap;
// width: calc(100% - 120px);
// overflow-x: auto;
.signleTab {
width: 215px;
position: relative;
display: inline-block;
.leftIcon {
width: 150px;
text-align: center;
cursor: pointer;
& > .pregressIcon {
width: 60px;
height: 60px;
}
}
& > .arrowSquare {
position: absolute;
top: 25px;
right: 0;
}
}
}
}
</style>