Vue3 list vertical scrolling (including page turning effect using swiper)

1. Use element-plus table for scrolling:

Needs that can be met: The table scrolls vertically line by line, similar to a revolving lantern.
Unsatisfied needs: The table is paginated and scrolls vertically, which has the effect of turning pages.

Code:
<template>
	<el-table
      :data="tableData"
      :show-overflow-tooltip="true"
      class="alarmTable"
    >
    <el-table-column
        type="index"
        width="134"
        align="center"
        label="序号">
        <template #default="scope">
          <span class="text">{
    
    {
    
    (scope.$index+1)+(currentPage-1)*(pageSize)}}</span>
        </template>
      </el-table-column>
      <el-table-column prop="name" label="名称" align="left">
        <template #default="scope">
          <span class="name-text">{
    
    {
    
    scope.row.name}}</span>
        </template>
      </el-table-column>
      <el-table-column prop="money" label="金钱" align="center" />
  </el-table>
</template>
<script lang="ts">
import {
    
     defineComponent, onMounted, reactive, ref, toRefs, nextTick, onUnmounted } from 'vue'

export default defineComponent({
    
    
  name: 'rank',
  setup () {
    
    
    // 表格的数据类型
    interface tableType {
    
    
      name: string;
      money: number;
    }
    const data = reactive({
    
    
      tableData: [] as Array<tableType>, // 表格的数据
      currentPage: 1, // 当前展示的页码
      pageSize: 6, // 当前表格一页展示多少条数据
      tableDom: {
    
    } as HTMLElement, // 表格内容的dom
    })
    let timeInterval: NodeJS.Timer // 定时器的对象
    let tableScroll = ref(true) // 是否需要滚动

    onMounted(() => {
    
    
      // 初始化表格的数据
      list()
      scrollTable()
    })

    onUnmounted(()=> {
    
    
      clearInterval(timeInterval)
    })

    // 初始化表格的数据
    const list = () => {
    
    
      let arr:Array<tableType> = []
      for(let i = 0; i < 28; i++) {
    
    
        let randomData = Math.floor(Math.random() * 100)
        let obj = {
    
    
          name: '名称'+randomData,
          money: randomData
        }
        arr.push(obj)
      }
      data.tableData = arr
    }
	
	  // 表格的数据滚动
    const scrollTable = () => {
    
    
      nextTick(() => {
    
    
        // 获取当前表格内容的dom
        let table = document.getElementsByClassName('alarmTable')[0]
        data.tableDom = (table.getElementsByClassName('el-scrollbar__wrap')[0])! as HTMLElement
        // 鼠标放在表格内容,暂停滚动
        data.tableDom.addEventListener('mouseover', () => {
    
    
            tableScroll.value = false
        })
        // 鼠标移出表格内容,继续滚动
        data.tableDom.addEventListener('mouseout', () => {
    
    
          tableScroll.value = true
        })
        // 
        timeInterval = setInterval(() => {
    
    
            if (tableScroll.value) {
    
    
              // 每次内容滚动的距离
              data.tableDom.scrollTop += 1
              if (data.tableDom.clientHeight + data.tableDom.scrollTop == data.tableDom.scrollHeight) {
    
    
                data.tableDom.scrollTop = 0
              }
            }
        }, 10)
      })
    }
    
    return {
    
    
      ...toRefs(data)
    }
  }
})
</script>
<style lang="scss" scoped>
.alarmTable {
    
    
    margin-top: 40px;
    height: 623px;
    overflow: hidden;
    scroll-behavior: smooth;
}
</style>
<style lang="scss">
  .el-table, .el-table::before,
  .el-table--border .el-table__inner-wrapper::after, .el-table--border::after, .el-table--border::before, .el-table__inner-wrapper::before {
    
    
    background: transparent!important;
  }
  .el-table th, .el-table__cell>.cell {
    
    
    height: 88px;
    padding: 0;
    font-size: 28px;
    font-weight: 400;
    color: #FFFFFF;
    line-height: 88px!important;
  }
  .el-table thead {
    
    
    font-size: 28px;
    font-weight: 600;
    color: #fff!important;
  }
  .el-table tr{
    
    
    background: transparent!important;
    &:nth-child(2n) {
    
    
      background:  rgba(49, 250, 233, 0.1)!important;
    }
  }
  .el-table th.el-table__cell {
    
    
    height: 88px;
    padding: 0;
    background:  rgba(237, 250, 49, 0.1)!important;
  }
  .el-table tr:hover>td {
    
    
    cursor: pointer;
    background-color: rgba(0,148,255,0.3) !important;
  }
  .el-table td.el-table__cell, .el-table th.el-table__cell.is-leaf {
    
    
    border-bottom: none!important;
  }
</style>
Effect:

Insert image description here

2. Use Swiper to scroll:

1、文档说明https://swiperjs.com/vue
2、下载swiper说明:
The introduction of the higher version (10.0.2) Autoplaywill report an error, so I downloaded 7.4.1the version ( npm install [email protected])

If version 7.4.1 is not easy to use, you can refer to this article: https://blog.csdn.net/qq_36131788/article/details/121083045

3、安装swiper成功后在 main.ts 文件中引入css:
import 'swiper/css'
Code:
<template>
    <div class="swiper-components">
        <div class="thead">
            <div v-for="(item,index) in theadData" :key="index" class="thead-tr">{
    
    {
    
     item }}</div>
        </div>
        <swiper
            :slides-per-view="1"
            :autoplay="{ delay: 2000, disableOnInteraction: false }"
            :direction="'vertical'"
            :scrollbar="{ draggable: false }"
            :loop="true"
            :modules="modules"
            class="swiper-content"
            >
            <swiper-slide v-for="(item, index) in tableData" :key="index">
                <div class="swiper-item" v-for="(subItem, subIndex) in item" :key="subIndex">
                    <div class="swiper-td">{
    
    {
    
     subItem.index }}</div>
                    <div class="swiper-td">{
    
    {
    
     subItem.name }}</div>
                    <div class="swiper-td">{
    
    {
    
     subItem.money }}</div>
                </div>
            </swiper-slide>
            </swiper>
    </div>
  </template>

<script lang="ts">
import {
    
     defineComponent, onMounted, reactive, toRefs } from 'vue'
// 引入swiper核心和所需模块
import  {
    
    Autoplay} from 'swiper'
// 引入swiper所需要的组件
import {
    
     Swiper, SwiperSlide } from 'swiper/vue'

export default defineComponent({
    
    
  name: 'SwiperComponents',
  components: {
    
    
    Swiper,
    SwiperSlide
  },
  setup () {
    
    
    // 表格的数据类型
    interface tableType {
    
    
      index: number | string;
      name: string;
      money: number;
    }
    const data = reactive({
    
    
      tableData: [] as Array<tableType>[], // 列表需要的数据
      modules: [Autoplay], // 这个是自动播放的重点,没有这个不能自动播放!
      slidesCount: 6, // 每次滑动的数据数量
      theadData: ['序号', '名称', '金钱'] // 表格表头
    })

    onMounted(() => {
    
    
      init()
    })

    // 数据初始化
    const init = () => {
    
    
      // 首先拿到请求的数据
      let arr = []
      for (let i = 0; i < 30; i++) {
    
    
        const obj = {
    
    
          index: i + 1,
          name: '987654',
          money: Math.floor(Math.random() * 100)
        }
        arr.push(obj)
      }

      // 根据一页要展示的数量进行数据的处理
      for (let i = 0; i < arr.length; i += data.slidesCount) {
    
    
        let obj = arr.slice(i, i + data.slidesCount)
        data.tableData.push(obj)
      }
    }

    return {
    
    
      ...toRefs(data)
    }
  }
})
</script>

  <style lang="scss" scoped>
  .swiper-components {
    
    
    margin-top: 40px;
    .thead {
    
    
        display: flex;
        justify-content: space-between;
        background: rgba(49,150,250,0.1);
        padding: 24px 40px 24px 34px;
        &-tr {
    
    
            font-size: 28px;
            font-weight: 600;
            color: #FFFFFF;
            line-height: 40px;
        }
    }
    .swiper-content {
    
    
        height: 528px;
        .swiper-item {
    
    
            display: flex;
            justify-content: space-between;
            &:nth-child(2n) {
    
    
                background: rgba(49,150,250,0.1);
            }
        }
        .swiper-td {
    
    
            padding: 24px 0;
            font-size: 28px;
            font-weight: 400;
            color: #FFFFFF;
            line-height: 40px;
            &:first-child {
    
    
                width: 134px;
                text-align: center;
            }
            &:last-child {
    
    
                width: 140px;
                margin-right: 40px;
                text-align: center;
            }
        }
    }
  }
  </style>

Effect:

Insert image description here

3. Use Swiper to click left and right to turn pages (the style should be adjusted according to actual needs):

<template>
	<swiper-slide v-for="(item, index) in 10" :key="index" class="swiper-single">
	    <div class="video-single">
	      <div class="video-content">
	        <video
	        controls
	        controlslist="nodownload noplaybackrate"
	        disablePictureInPicture="true"
	        disableRemotePlayback="true"
	        src="https://www.runoob.com/try/demo_source/movie.mp4"></video>
	      </div>
	      <div class="video-name">视频{
    
    {
    
     index }}</div>
	    </div>
	</swiper-slide>
</template>

<script lang="ts">
import {
    
     defineComponent, toRefs } from 'vue'
// 引入swiper所需要的组件
import {
    
     Swiper, SwiperSlide } from 'swiper/vue'
import {
    
     Pagination, Navigation } from 'swiper'

export default defineComponent({
    
    
  name: 'VideoDialog',
  components: {
    
    
    Swiper,
    SwiperSlide
  },
  setup () {
    
    
    const data = reactive({
    
    
      modules: [Pagination, Navigation]
    })
    
    return {
    
    
      ...toRefs(data)
    }
  }
})
</script>
<style lang="scss">
  .swiper-button-prev, .swiper-button-next {
    
    
    cursor: pointer;
    z-index: 200;
    position: absolute;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    display: inline-block;
    width: 59px;
    height: 59px;
    background: rgba(49,150,250,0.1);
    border-radius: 3px;
    border: 2px solid #3196FA;
  }
  .swiper-button-prev {
    
    
    &::after {
    
    
      content: '';
      position: absolute;
      z-index: 5;
      top: 10px;
      left: 4px;
      display: inline-block;
      width: 12px;
      border-right: 18px solid #3196fa;
      border-left: 0 solid transparent;
      border-top: 18px solid transparent;
      border-bottom: 18px solid transparent;
    }
    &::before {
    
    
      content: '';
      position: absolute;
      z-index: 6;
      top: 10px;
      left: 8px;
      display: inline-block;
      width: 12px;
      border-right: 18px solid #1c4577;
      border-left: 0 solid transparent;
      border-top: 18px solid transparent;
      border-bottom: 18px solid transparent;
    }
  }
  .swiper-button-next  {
    
    
    margin-left: 154px;
    &::after {
    
    
      content: '';
      position: absolute;
      z-index: 5;
      top: 10px;
      right: 4px;
      display: inline-block;
      width: 12px;
      border-left: 18px solid #3196fa;
      border-right: 0 solid transparent;
      border-top: 18px solid transparent;
      border-bottom: 18px solid transparent;
    }
    &::before {
    
    
      content: '';
      position: absolute;
      z-index: 6;
      top: 10px;
      right: 8px;
      display: inline-block;
      width: 12px;
      border-left: 18px solid #1c4577;
      border-right: 0 solid transparent;
      border-top: 18px solid transparent;
      border-bottom: 18px solid transparent;
    }
  }
  .swiper-pagination{
    
    
    z-index: 200;
    position: absolute;
    bottom: 23px;
    left: 630px;
    width: 95px;
    white-space: nowrap;
    font-size: 24px;
    font-weight: 400;
    color: #CCCCCC;
    line-height: 14px;
  }
  .swiper-pagination-current {
    
    
    color: #3196FA;
  }
</style>

Effect:

Insert image description here

4. When using Swiper to play automatically, change the data to play from the first page:

Reference link

Insert image description here
Insert image description here

Original component renderings:

Insert image description here

Completed renderings:

Insert image description here

Guess you like

Origin blog.csdn.net/Y1914960928/article/details/132583878