vue 实现一个可以横向拖动的步骤条

vue yekong

数据大屏开发中,需要实现一个步骤条的效果,但是步骤条的长度可能会很大超过了当前显示区域,所以我们需要一个可以鼠标横向拖动的效果。

vue 实现一个可以横向拖动的步骤条

动态拖动效果

开发环境

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: '无为市人'
}]
喜欢