vue封装滚动表格

1.组件的使用

<div class="bottomcenterdetail">
                    <el-row class="goodshort">
                      <el-col :span="6">序号</el-col><el-col :span="12">货品名称</el-col><el-col :span="6" style="text-align:right">滞留时长(天)</el-col>
                    </el-row>
                     <div style="height:93%;  overflow: hidden;"> 
                         <autoScroll :data="timeoutList" :speed="0.5" :waitTime="500" :singleHeight="100" v-if="timeoutList.length>0">
                              <el-row v-for="(item,index) in timeoutList" :key="index" class="goodshortli">
                                <el-col class="goodshortlist" :span="6">{{index+1}}</el-col>
                                <el-col class="goodshortlist" :span="12" :title="item.goodsName">{{item.goodsName}}</el-col>
                                <el-col class="goodshortlist" style="text-align:right" :span="6">{{item.stayTime}}</el-col>
                             </el-row>
                       </autoScroll>
                        <div v-else class="zanwushuju">暂无数据</div>
                     </div>
</div>

 2.数据格式


import autoScroll from "@/components/houseCard/autoScroll.vue"
export default {
    name:'first',
      components: { autoScroll },
    data(){
        return{
          timeoutList:[{goodsName:'小马',stockNumber:'1'}],
        }
    }
}

 3.组件样式

.bottomcenterdetail{
    width:100%;
    height:95%;
    .goodshort{
        height:30px;
        line-height:30px;
        color:rgb(109, 131, 140);
        font-size:12px;
        background:rgb(1, 40, 55)
    }
    .goodshortlist{
        height: 30px;
        font-size: 12px;
        padding:0px 6px;
        font-family: MicrosoftYaHei;
        line-height: 30px;
        overflow: hidden;//(文字长度超出限定宽度,则隐藏超出的内容)
        white-space: nowrap;//(设置文字在一行显示,不能换行)
        text-overflow: ellipsis;//(规定当文本溢出时,显示省略符号来代表被修剪的文本)
    }
    .goodshortli{
        color:#3DE1ED
    }
      .goodshortli:nth-child(odd){
        background-image: url(../image/goodlistbg.png);
           background-repeat: no-repeat; /* 取消重复平铺 */
      }
      .goodshortli:nth-child(-n+6){
        color:#FE0000;
      }
      .goodshortli:nth-child(n+7):nth-child(-n+11){
        color:#FDD35D;
      }
}

 4.autoScroll.vue,封装好的组件

<template>
  <div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
    <div class="scroll-inner-box" ref="scrollBox">
      <div class="scroll-item-box" ref="scrollItemBox">
        <slot></slot>
      </div>
      <div v-if="showSecond" class="scroll-item-box">
        <slot></slot>
      </div>
    </div>
  </div>
</template>
  <script>
export default {
  name: "autoScroll",
  props: {
    list: {
      type: Array,
      default: () => [
        // { name: "张三1" },
        // { name: "张三2" },
      ],
    },
    speed: {
      type: Number,
      default:'',
    },
    //滚动作单步运动时的单纯运动距离
    singleHeight: {
      type: Number,
      default: '',
    },
    //单步运动的时间间隔
    waitTime: {
      type: Number,
      default: '',
    },                                                                                                                                      
  },
  data() {
    return {
      rafId: null,
      y: 0,
      showSecond: false,
      controleHeight: 0,
    };
  },
  watch: {
    list: {
      handler(newVal) {
        var that = this;
        this.$nextTick(() => {
          if (newVal && newVal.length > 0) {
            let scrollBox = that.$refs.scrollBox;
            let outer = that.$refs.outer;
 
            if (this.myReq) {
              cancelAnimationFrame(this.myReq);
            }
            // 开启动画
            if (this.canRun())
             this.reqAnimationFrame();
            // 手动滚动到底部时滚动条重置到最上边,同时滚动盒子重置为top:0
            outer.addEventListener("scroll", function () {
              if (
                outer.scrollTop + outer.clientHeight + 4 >= outer.scrollHeight
              ) {
                outer.scrollTop = 0;
                that.y = 0;
                scrollBox.style.top = 0;
              }
            });
          }
        });
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {
  this.$nextTick(()=>{
      window.addEventListener("resize", this.listenResizeFn);
      this.onMouseover()
      this.onMouseleave()
  })

  },
  methods: {
    listenResizeFn() {
      cancelAnimationFrame(this.myReq);
      if (this.canRun()) this.reqAnimationFrame();
    },
    // 鼠标移入
    onMouseover() {
      clearTimeout(this.timer);
      cancelAnimationFrame(this.myReq);
    },
       // 鼠标离开
    onMouseleave() {
      if (this.canRun())
       this.reqAnimationFrame();
    },
    canRun() {
      let scrollItemBox = this.$refs.scrollItemBox;
      let scrollBox = this.$refs.scrollBox;
      let outer = this.$refs.outer;
      // 开启动画条件:滚动盒子(scrollBox)高度高于外层容器(outer)高度
      if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
        this.showSecond = false;
        outer.scrollTop = 0;
        this.y = 0;
        scrollBox.style.top = 0;
        return false;
      } else {
        this.showSecond = true;
        return true;
      }
    },
    //获取dom元素的高度:content+padding+margin+border
    getComputedHeight(dom) {
      let computedStyle = getComputedStyle(dom);
 
      let computedHeight =
        dom.offsetHeight +
        parseFloat(computedStyle.marginTop) +
        parseFloat(computedStyle.marginBottom);
      return computedHeight;
    },
    reqAnimationFrame() {
      //外层容器
      let outer = this.$refs.outer;
      //滚动盒子
      let scrollBox = this.$refs.scrollBox;
      //滚动盒子下边的第一个scroll-item-box,
      let scrollItemBox = this.$refs.scrollItemBox;
 
      //滚动速度
      this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;
 
      //取第一个scrollItemBox高度
      let definedHeight = this.getComputedHeight(scrollItemBox);
      //持续滚动
      this.y = this.y + this.speed;
      scrollBox.style.top = -this.y + "px";
 
      //====添加滚动间隔控制====开始
      if (this.singleHeight >= 20 && this.waitTime > 500) {
        if (this.controleHeight >= this.singleHeight) {
          cancelAnimationFrame(this.myReq);
          this.controleHeight = 0;
          this.timer = setTimeout(() => {
            if (this.canRun) this.reqAnimationFrame();
          }, this.waitTime);
          return;
        } else {
          // 一次移动高度未达到指定距离继续执行动画
          this.controleHeight += this.speed;
        }
      }
      //====添加滚动间隔控制====结束
 
      //当滚动到第一个scroll-item-box高度时scrollBox重置为top:0,视觉上是无缝滚动
      if (this.y >= definedHeight) {
        this.y = 0;
      }
      this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
    },
  },
  destroyed() {
    window.removeEventListener("resize", this.listenResizeFn);
    cancelAnimationFrame(this.myReq);
    if (this.timer) clearTimeout(this.timer);
  },
};
</script>
  <style lang="less" scoped>
.scroll-outer {
  height: 100%;
  overflow-x: hidden;
  position: relative;
  &::-webkit-scrollbar {
    width: 0.3vw;
  }
  &:hover::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
    border-radius: 0.1vw;
    background-color: #295099;
    opacity: 1;
    // display: none;
  }
  &:hover::-webkit-scrollbar-thumb {
    opacity: 1;
    border-radius: 0.1vw;
    -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
    background-color: #0ba9ea;
  }
}
.scroll-inner-box {
  height: auto;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
</style>
  

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z_Xshan

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值