意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

vue如何实现新闻列表垂直滚动,方法是什么

来源:恒创科技 编辑:恒创科技编辑部
2024-01-21 12:46:59

今天我们来学习关于“vue如何实现新闻列表垂直滚动,方法是什么”的内容,下文有详解方法和实例,内容详细,逻辑清晰,有需要的朋友可以参考,希望大家阅读完这篇文章后能有所收获,那么下面就一起来了解一下吧。


本文实例为大家分享了vue实现列表垂直无缝滚动的具体代码,供大家参考,具体内容如下


vue如何实现新闻列表垂直滚动,方法是什么

实现新闻列表的轮播(如下图)

上代码

封装的so-marquee.vue

<template>
  <div
    class="marquee-wrapper"
    :style="{ width: realWidth + 'px' }"
  >
    <div
      class="marquee-container"
      :style="{ height: realHeight + 'px' }"
      :class="className"
    >
      <ul
        ref="marqueeCon"
        :id="tooltipId"
        class="marquee-content"
        :class="{ anim: animate === true}"
        @mouseenter="handleStop()"
        @mouseleave="handleUp()"
      >
        <li
          v-for="(item,index) in realData"
          :key="`${tooltipId}-${item.id}-${index}`"
          class="marquee-item"
          :style="{ height: itemHeigth + 'px' }"
          @click="handleClick(item)"
        >
          <slot name="itemCon" :item="item"></slot>
        </li>
      </ul>
    </div>
  </div>
</template>
<script>
import { parseToNum, generateId } from '@/utils/util'

export default {
  name: "so-marquee",
  props: {
    /*
    * 可接受传参
    * data     列表数据
    * className   自定义类名
    * width     列表宽度,默认值:400
    * height    列表高度,默认值:200
    * showNumber  可视的条目数,默认值:5
    * speed     轮播速度,默认值:1000
    * */
    //列表数据
    data: {
      type: Array,
      default: () => [],
    },
    //自定义类名
    className: String,
    //列表宽度,默认值:400
    width: {
      type: [Number, String],
      default: 400
    },
    //列表高度,默认值:200
    height: {
      type: [Number, String],
      default: 200
    },
    //可视的条目数,默认值:5
    showNumber: {
      type: [Number, String],
      default: 5
    },
    //轮播速度,默认值:1000
    speed: {
      type: [Number, String],
      default: 1000
    }
  },
  data() {
    return {
      intnum: undefined,
      animate: false
    };
  },
  computed: {
    tooltipId() {
      return `marquee-con-${ generateId() }`;
    },
    realWidth() {
      return parseToNum(this.width)
    },
    realHeight() {
      return parseToNum(this.height)
    },
    realShowNumber() {
      return parseToNum(this.showNumber)
    },
    realSpeed() {
      return parseToNum(this.speed) < 1000 ? 1000 : parseToNum(this.speed)
    },
    itemHeigth() {
      return this.realHeight / this.realShowNumber
    },
    realData() {
      return JSON.parse(JSON.stringify(this.data))
    }
  },
  mounted() {
    if (this.realData.length > this.realShowNumber) {
      this.scrollUp();
    }
  },
  methods: {
    scrollUp() {
      // eslint-disable-next-line no-unused-vars
      this.intnum = setInterval(_ => {
        this.animate = true;
        setTimeout(() => {
          this.realData.push(this.realData[0]);  // 将数组的第一个元素添加到数组的
          this.realData.shift();        //删除数组的第一个元素
          this.animate = false;      // margin-top 为0 的时候取消过渡动画,实现无缝滚动
        }, this.realSpeed / 2)
        this.$once('hook:beforeDestroy', () => {
          this.cleanup()
        })
      }, this.realSpeed);
    },
    handleStop() {
      this.cleanup()
    },
    handleUp() {
      this.scrollUp();
    },
    handleClick(row) {
      this.$emit('handleClick', row)
    },
    cleanup() {
      if (this.intnum) {
        clearInterval(this.intnum);
        this.intnum = null;
      }
    }
  },
  beforeDestroy() {
    this.cleanup();
  },
  deactivated() {
    this.cleanup();
  },
  watch: {
    animate(flag) {
      this.marqueeCon = this.$refs.marqueeCon
      if (flag) {
        this.marqueeCon.style.marginTop = `-${ this.itemHeigth }px`
      } else {
        this.marqueeCon.style.marginTop = 0
      }
    },
  }
};
</script>
<style scoped lang="scss">
  .marquee-container {
    overflow: hidden;
  }

  .marquee-content {
    position: relative;
  }

  .anim {
    transition: all 0.5s;
  }

  .marquee-item {
    display: flex;
    align-items: center;
    justify-content: space-around;
  }
</style>

parseToNum方法

export function parseToNum(value) {
  if (value !== undefined) {
    value = parseInt(value, 10)
    if (isNaN(value)) {
      value = null;
    }
  }
  return value
}

generateId 方法

export const generateId = function() {
  return Math.floor(Math.random() * 10000);
};

父组件调用

<template>
  <div id="app">
    <so-marquee
      :data="jsonData"
      :height="200"
      :showNumber="4"
      :speed="500"
      class="my-ui-marquee"
      @handleClick="handleMarqueeClick"
    >
      <template v-slot:itemCon="{item}">
        <div>{{ item.id }}</div>
        <div>{{ item.name }}</div>
        <div>{{ item.date }}</div>
      </template>
    </so-marquee>
  </div>
</template>

<script>
import soMarquee from './components/so-marquee'

export default {
  name: 'App',
  data() {
    return {
      jsonData: [
        {
          id: 1,
          name: "开会通知",
          date: "2020-02-01"
        },
        {
          id: 2,
          name: "放假通知",
          date: "2020-02-02"
        },
        {
          id: 3,
          name: "停水通知",
          date: "2020-02-03"
        },
        {
          id: 4,
          name: "停电通知",
          date: "2020-02-04"
        },
        {
          id: 5,
          name: "停车通知",
          date: "2020-02-05"
        },
        {
          id: 6,
          name: "奖励通知",
          date: "2020-02-06"
        },
        {
          id: 7,
          name: "处分通知",
          date: "2020-02-07"
        },
        {
          id: 8,
          name: "处分8通知",
          date: "2020-02-08"
        },
        {
          id: 9,
          name: "处分9通知",
          date: "2020-02-09"
        },
        {
          id: 10,
          name: "处分10通知",
          date: "2020-02-10"
        },
      ]
    }
  },
  components: {
    soMarquee
  },
  methods: {
    handleMarqueeClick(row) {
      alert(`当前点击的第${row.id}行`)
    }
  }
}
</script>

<style scoped lang="scss">
.my-ui-marquee {
  ::v-deep.marquee-item {
    cursor: pointer;
  }
}
</style>

以上就是关于“vue如何实现新闻列表垂直滚动,方法是什么”的介绍了,感谢各位的阅读,如果大家想要了解更多相关的内容,欢迎关注恒创科技,小编每天都会为大家更新不同的知识。
上一篇: vue弹窗关闭刷新实现过程的常见问题怎样解决 下一篇: 手机怎么远程登录云服务器?