Edward 2023-04-10 10:26 采纳率: 0%
浏览 96
已结题

vue3页面滚动及暂停按钮出现问题

vue3中自制了一个页面滚动功能和一个暂停、滚动按钮,目前出现的问题是暂停、滚动按钮有时好使有时失效,并且页面自动滚动偶尔会出现页面抖动的问题,求帮忙解决一下
以下是代码


<template>
  <div class="home" v-on:scroll="onScroll" ref="scrollContainer">
    <div class="header">仓库看板</div>
    <div class="home-table">
      <table class="homeTable1" border="1" cellspacing="0">
        <thead class="table-head">
          <th class="bgPrimary">库区</th>
          <th class="bgPrimary">层数</th>
          <th class="bgPrimary" v-for="(item, index) in 22" :key="index">
            {{ (item = item < 10 ? "00" + item : "0" + item) }}
          </th>
        </thead>
        <tbody v-for="(item, index) in filteredList" :key="index">
          <tr v-for="(items, indexs) in item.list" :key="indexs">
            <th
              :rowspan="item.list.length"
              class="bgPrimary"
              v-if="indexs == 0"
            >
              {{ item.name }}
            </th>
            <th class="bgPrimary">{{ item.list.length - indexs }}</th>
            <td
              v-for="(itemss, indexss) in items.info"
              :key="indexss"
              :class="
                itemss.volmueType == 0
                  ? 'colorEmpty'
                  : itemss.volmueType > 0 && itemss.volmueType < 50
                  ? 'colorMore'
                  : itemss.volmueType >= 50 && itemss.volmueType <= 100
                  ? 'colorMore'
                  : itemss.volmueType > 100
                  ? 'colorMore'
                  : 'colorPrimary'
              "
              :style="itemss.volmueType == '-1' ? 'border:none' : ''"
            >
              {{ itemss.MatName }}
            </td>
          </tr>
          <div class="space"></div>
        </tbody>
      </table>
    </div>
    <div class="home-table">
      <table class="homeTable1" border="1" cellspacing="0">
        <thead>
          <th class="bgPrimary">库区</th>
          <th class="bgPrimary">层数</th>
          <th class="bgPrimary" v-for="(item, index) in 10" :key="index">
            {{ (item = item < 10 ? "00" + item : "0" + item) }}
          </th>
        </thead>
        <tbody v-for="(item, index) in filteredElseList" :key="index">
          <tr v-for="(items, indexs) in item.list" :key="indexs">
            <th
              :rowspan="item.list.length"
              class="bgPrimary"
              v-if="indexs == 0"
            >
              {{ item.name }}
            </th>
            <th class="bgPrimary">{{ item.list.length - indexs }}</th>
            <td
              v-for="(itemss, indexss) in items.info"
              :key="indexss"
              :class="
                itemss.volmueType == 0
                  ? 'colorEmpty'
                  : itemss.volmueType > 0 && itemss.volmueType < 50
                  ? 'colorMore'
                  : itemss.volmueType >= 50 && itemss.volmueType <= 100
                  ? 'colorMore'
                  : itemss.volmueType > 100
                  ? 'colorMore'
                  : 'colorPrimary'
              "
            >
              {{ itemss.MatName }}
            </td>
          </tr>
          <div class="space"></div>
        </tbody>
      </table>
    </div>
    <el-button type="primary" class="floatBtn" @click="handleOnscroll">{{
      isPaused ? "开始滚动" : "暂停滚动"
    }}</el-button>
  </div>
</template>
<script>
import { onMounted, ref, onUnmounted, computed } from "vue";
import { ExecJSON2 } from "@/api/mainPage";
export default {
  name: "mainPage",
  setup() {
    const tableData = ref([]);
    const rowstyles = ref();
    const areaData = ref(new Array());
    const timer = ref();

    const scrolling = ref(false);
    const timeoutId = ref(null);
    const scrollContainer = ref(null);
    const intervalId = ref(null);
    const isPaused = ref(false);

    const filteredList = computed(() => {
      if (!tableData.value) {
        return [];
      }
      return tableData.value.filter((item) => item.list.length > 1);
    });

    const filteredElseList = computed(() => {
      return tableData.value.filter((item) => item.list.length == 1);
    });

    onMounted(() => {
      getAllData();
      onScroll();
      timer.value = setInterval(() => {
        getAllData();
        location.reload();
      }, 30 * 60 * 1000);
    });

    onUnmounted(() => {
      clearInterval(timer);
    });
    const getAllData = () => {
      const param = {
        Code: "KB_01",
        Data: [
          {
            WarehouseCode: "01",
          },
        ],
      };
      ExecJSON2(param)
        .then(async (res) => {
          if (res.Success == "01") {
            tableData.value = await bubbleSort(res.Data1);
          }
        })
        .catch((err) => {
          console.log(err, 19);
        });
    };
    const bubbleSort = async (array) => {
      for (let i = 0; i < array.length; i++) {
        array[i].info = JSON.parse(array[i].info);
        let newDataList = [];
        for (let j = 0; j < array[i].info.length; j++) {
          newDataList.push(array[i].info[j]);
          let curNum = parseInt(array[i].info[j].WarehouseLocation, 10);

          if (array[i].info[j + 1]) {
            let nextNum = parseInt(array[i].info[j + 1].WarehouseLocation, 10);

            if (nextNum - curNum > 1) {
              for (let j = 1; j < nextNum - curNum; j++) {
                newDataList.push({
                  MatName: "",
                  WarehouseLocation: (curNum + j).toString().padStart(3, "0"),
                  WarehouseLayers: array[i].info[j].WarehouseLayers,
                  WarehouseArea: array[i].info[j].WarehouseArea,
                  Volume: "0.00",
                  NewVolume: "0.00",
                  Quantity: "0",
                  SafetyStock: "0",
                  volmueType: "-1",
                });
              }
            }
          }

          array[i].info[j].volmuePersent =
            parseInt(array[i].info[j].NewVolume) == "0"
              ? " "
              : Math.round(
                  (parseFloat(array[i].info[j].Volume) /
                    parseFloat(array[i].info[j].NewVolume)) *
                    10000
                ) /
                  100 +
                "%";

          array[i].info[j].volmueType =
            parseInt(array[i].info[j].NewVolume) == "0"
              ? 0
              : Math.round(
                  (parseFloat(array[i].info[j].Volume) /
                    parseFloat(array[i].info[j].NewVolume)) *
                    10000
                ) / 100;
        }
        array[i].info = newDataList;
      }

      array = await groupArr(array, "WarehouseArea");

      return array;
    };

    const groupArr = (list, field) => {
      var obj = {};
      for (var i = 0; i < list.length; i++) {
        for (let item in list[i]) {
          if (item == field) {
            obj[list[i][item]] = {
              list: obj[list[i][field]] ? obj[list[i][field]].list : [],
              name: list[i][field],
            };
          }
        }
        obj[list[i][field]].list.push(list[i]);
      }
      var att = [];
      for (let item in obj) {
        att.push({
          list: obj[item].list,
          name: obj[item].name,
        });
      }
      return att;
    };
    const scrollDirection = ref("down");
    const isAutoScrolling = ref(true);

    const onScroll = () => {
      if (isPaused.value) return;

      // 停止自动滚动
      clearTimeout(timeoutId.value);

      // 设置滚动状态
      scrolling.value = true;

      // 滚动页面
      const windowHeight = window.innerHeight;
      const contentHeight = document.documentElement.scrollHeight;
      let position = window.pageYOffset;
      let reachedTop = false;

      intervalId.value = setInterval(() => {
        if (scrollDirection.value == "down") {
          position += 1; // 每次滚动1px
          window.scrollTo(0, position);
          if (position + windowHeight >= contentHeight) {
            clearInterval(intervalId.value);
            scrolling.value = false;
            scrollDirection.value = "up";
            // 两秒后重新开始滚动
            timeoutId.value = setTimeout(() => {
              onScroll();
            }, 2000);
          }
        } else {
          if (position === 0) {
            reachedTop = true;
          }

          if (!reachedTop) {
            position -= 1; // 每次滚动1px
            window.scrollTo(0, position);
          }

          if (reachedTop && position === 0) {
            clearInterval(intervalId);
            scrolling.value = false;
            scrollDirection.value = "down";
            reachedTop = false;
            // 两秒后重新开始滚动
            timeoutId.value = setTimeout(() => {
              onScroll();
            }, 2000);
          }
        }
      }, 20); // 每20毫秒滚动一次
    };

    const handleOnscroll = () => {
      if (isPaused.value) {
        // 继续滚动
        isPaused.value = false;
        onScroll();
      } else {
        // 暂停滚动
        isPaused.value = true;
        clearTimeout(timeoutId.value);
        clearInterval(intervalId.value);
      }

      console.log("isPaused.value:" + isPaused.value);
      console.log("scrolling.value:" + scrolling.value);
      console.log("intervalId.value:" + intervalId.value);
      console.log("timeoutId.value:" + timeoutId.value);
    };

    return {
      getAllData,
      bubbleSort,
      tableData,
      rowstyles,
      areaData,
      groupArr,
      filteredList,
      filteredElseList,
      timer,
      scrolling,
      timeoutId,
      onScroll,
      scrollContainer,
      scrollDirection,
      isAutoScrolling,
      handleOnscroll,
      intervalId,
      isPaused,
    };
  },
  mounted() {
    this.$refs.scrollContainer.addEventListener("scroll", this.onScroll);
  },

  beforeUnmount() {
    this.$refs.scrollContainer.removeEventListener("scroll", this.onScroll);
  },
};
</script>
<style lang="less" scoped>
.home {
  width: 100%;
  .header {
    font-size: 1.2rem;
    color: #409eff;
    position: sticky;
    top: 0;
    background: #f2f6fc;
  }
  .home-table {
    display: flex;
    table {
      table-layout: fixed;
      height: 100%;
      width: 100%;
    }
    .table-head {
      position: sticky;
      top: 1.5rem;
    }
  }

  table,
  th {
    text-align: center;
    border: 0.5px solid #f5f6f9;
    border-collapse: collapse;
    color: #ffffff;
    font-size: 0.7rem;
    background: #f2f6fc;
  }

  .space {
    width: 100%;
    height: 3rem;
  }

  td {
    color: black;
    height: 3rem;
  }

  table td {
    margin: 0 auto;
  }

  .colorPrimary {
    background: #f2f6fc !important;
  }

  .bgPrimary {
    background: #409eff !important;
  }

  .colorEmpty {
    background: #ffffff !important;
  }
  .colorSimple {
    background: #e3f6f5 !important;
  }
  .colorMore {
    background: #bae8e8 !important;
  }
  .colorOverload {
    background: #2c698d !important;
  }

  .floatBtn {
    position: fixed;
    right: 1rem;
    bottom: 3rem;
  }
}
</style>


  • 写回答

7条回答 默认 最新

  • 不会么么哒 2023-04-10 10:37
    关注

    v3 用v2写法??

    评论

报告相同问题?

问题事件

  • 系统已结题 4月18日
  • 赞助了问题酬金15元 4月10日
  • 创建了问题 4月10日