看板无缝滚动

之前用的插件来着,最近公司统一用一个盒子啥的,版本较低,用插件直接不显示,于是自己封装一个组件实现无缝滚动,满足基本需求。

组件如下:

<!--
 * @Author: 方志良 
 * @Date: 2024-08-1 13:05:49
 * @LastEditors: 方志良 
 * @LastEditTime: 2024-08-01 16:10:08
 * @FilePath: \biweiman-screen\src\view\SeamScroll.vue
 * 
-->
<template>
  <div :style="{ transform: `translateY(${scrollPx}px)` }">
    <div style="overflow: hidden;" @mouseover="mouseoverFn" @mouseout="mouseoutFn">
      <slot></slot>
    </div>
    <div style="overflow: hidden;" v-if="listLength * lineHeight > singleHeight" @mouseover="mouseoverFn"
      @mouseout="mouseoutFn">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SeamScroll',
  props: {
    //对应的可视父盒子高度
    singleHeight: {
      type: Number,
      default: 0,
      required: true
    },
    //单行高度,每一项子盒子高度
    lineHeight: {
      type: Number,
      default: 0,
      required: true
    },
    //列表的length
    listLength: {
      type: Number,
      default: 0,
      required: true
    },
    //是否开启自动滚动
    isAutoRoll: {
      type: Boolean,
      default: true,
    },
    // 是否开启鼠标悬停
    hover: {
      type: Boolean,
      default: true,
    },
    // 控制滚动方向,up向上滚动,其他任何字符串向下
    direction: {
      type: String,
      default: "up"
    },
    //滚动1px所需要的毫秒数,越小越快
    singleWaitTime: {
      type: Number,
      default: 100
    },
  },
  data() {
    return {
      scrollPx: 0,//滚动的像素大小
      tableTimer: null
    };
  },
  methods: {
    mouseoverFn() {
      if (!this.hover) return
      clearInterval(this.tableTimer);
    },
    mouseoutFn() {
      clearInterval(this.tableTimer);
      this.tableTimerFun()
    },
    tableTimerFun() {
      //没开启自动滚动或者没有滚动条情况不滚动
      if (!this.isAutoRoll || this.listLength * this.lineHeight < this.singleHeight) return
      let count = 0;
      this.tableTimer = setInterval(() => {
        if (count < this.listLength * this.lineHeight) {
          this.scrollPx = this.direction === 'up' ? this.scrollPx - 1 : this.scrollPx + 1
          count++;
        } else {
          count = 0;
          this.scrollPxFn()
        }
      }, this.singleWaitTime);
    },
    scrollPxFn() {
      this.scrollPx = this.direction === 'up' ? 0 : -(this.listLength * this.lineHeight)
    }
  },

  mounted() {
    this.scrollPxFn()
    this.tableTimerFun()
  },
  beforeDestroy() {
    clearInterval(this.tableTimer);
  }
}
</script>

<style lang="less" scoped></style>

父组件中使用:



<template>
  <div class="middle">
    <table>
      <thead>
        <tr>
          <th>工位名称</th>
          <th>需求数量</th>
          <th>领取数量</th>
          <th>已消耗数量</th>
          <th>剩余数量</th>
        </tr>
      </thead>
      <tbody>
        <SeamScroll :singleHeight="350" :lineHeight="45" :listLength="materialTable.length">
          <tr v-for="(item, index) in materialTable" :key="index">
            <td>{{ item.stationName }}</td>
            <td>{{ item.requireQty }}</td>
            <td>{{ item.receiveQty
            }}</td>
            <td>{{ item.consumeQty
            }}</td>
            <td>{{ item.remainQty }}
            </td>
          </tr>
        </SeamScroll>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: 'screen',
  components: {
    SeamScroll: () =>
      import("./SeamScroll.vue"),
  },
  data() {
    return {
      materialTable: Array.from({ length: 1 }, (_, index) => ({
        stationName: `${index + 1}号工位`,
        requireQty: 12,
        receiveQty: 10,
        consumeQty: 3,
        remainQty: 7
      })),
    }
  },
}
</script>

<style lang="less" >
table {
  width: 100%;
  border-collapse: collapse;
  height: 400px;
  background-color: #083680;
}

th {
  color: #16c2e3;
  background-color: #032c6d;
}

td {
  color: #ffffff;
  overflow: hidden;
  /* 超出部分隐藏 */
  text-overflow: ellipsis;
  /* 使用省略号来表示被修剪的文本 */
  white-space: nowrap;
  /* 文本不换行 */
}

th,
tr {
  height: 45px;
  font-size: 25px;
  line-height: 45px;
  padding: 8px;
  text-align: center;
}

tr:nth-child(even) {
  /* 偶数行(从1开始计数,所以2, 4, 6...是偶数) */
  background-color: #0641a1;
}

tr:nth-child(odd) {
  /* 奇数行(1, 3, 5...) */
  background-color: #083680;
}

thead tr,
tbody tr {
  display: table;
  width: 100%;
  table-layout: fixed;
}

table tbody {
  display: block;
  overflow-y: hidden;
  width: 100%;
  height: 350px;
}
</style>

 

 

Vue 3 的看板滚动列表样式同样可以通过 CSS 进行设置,以下是一个基本的示例: ```html <template> <div class="board-container"> <div class="board-column" v-for="(column, index) in columns" :key="index"> <div class="column-header">{{ column.title }}</div> <div class="column-body" ref="columnBody" @scroll="handleScroll"> <div class="card" v-for="card in column.cards" :key="card.id">{{ card.title }}</div> </div> </div> </div> </template> <script> export default { data() { return { columns: [ { id: 1, title: 'To Do', cards: [ { id: 1, title: 'Task 1' }, { id: 2, title: 'Task 2' }, { id: 3, title: 'Task 3' } ] }, { id: 2, title: 'In Progress', cards: [ { id: 4, title: 'Task 4' }, { id: 5, title: 'Task 5' } ] }, { id: 3, title: 'Done', cards: [ { id: 6, title: 'Task 6' }, { id: 7, title: 'Task 7' }, { id: 8, title: 'Task 8' } ] } ] } }, methods: { handleScroll(event) { // do something on scroll } } } </script> <style> .board-container { display: flex; overflow-x: auto; height: 100%; } .board-column { flex: 0 0 300px; margin-right: 16px; } .column-header { font-weight: bold; margin-bottom: 16px; } .column-body { height: calc(100% - 36px); overflow-y: auto; border: 1px solid #ccc; border-radius: 4px; padding: 16px; } .card { background-color: #fff; box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); border-radius: 4px; margin-bottom: 16px; padding: 8px; } </style> ``` 在上述示例中,`.board-container` 是一个固定高度、可横向滚动的容器。`.board-column` 是每个看板列的样式设置,包括了 `flex`、`margin-right` 等。`.column-header` 是每个看板列标题的样式设置,包括了 `font-weight` 和 `margin-bottom` 等。`.column-body` 是每个看板列的滚动列表样式设置,包括了 `height`、`overflow-y`、`border`、`border-radius` 和 `padding` 等。在 `handleScroll` 方法中,可以获取到滚动事件的信息,并进行相应的处理。 注意,Vue 3 的看板组件需要使用 `v-for` 指令来渲染看板列和卡片。在上述示例中,使用了 `v-for="(column, index) in columns"` 来遍历看板列,使用了 `v-for="card in column.cards"` 来遍历看板列中的卡片。同时,每个看板列的滚动列表需要添加 `ref="columnBody"`,以便在 `handleScroll` 方法中获取到对应的滚动事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值