element-ui的table实现滚动加载,涵el-table组件封装一份

这篇具有很好参考价值的文章主要介绍了element-ui的table实现滚动加载,涵el-table组件封装一份。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 如果你是直接用的 el-table 组件;下面为一个示例

重点就是 a d d R o l l L i s t e n e r addRollListener addRollListener 函数,想快点弄上去看效果的直接弄这个函数吧
如果不在mounted中则一定要this.$nextTick(() => this.addRollListener())

addRollListener(cb) {
  const dom = this.$refs.myTable.bodyWrapper
  dom.addEventListener('scroll', () => {
    const scrollTop = dom.scrollTop
    // 变量windowHeight是可视区的高度
    const windowHeight = dom.clientHeight || dom.clientHeight
    // 变量scrollHeight是滚动条的总高度
    const scrollHeight = dom.scrollHeight || dom.scrollHeight
    if (scrollTop + windowHeight + 1 > scrollHeight) cb && cb()
  })
}

示例代码

<template>
  <div class="element-table-scroll">
    <el-table
      ref="myTable"
      v-loading="loading"
      :data="tableData"
      :height="500"
      border
      element-loading-background="rgba(0, 0, 0, 0.8)"
      class="table-left color-table"
    >
      <el-table-column label="序号" type="index" align="center" width="56" />
      <el-table-column
        prop="name"
        label="名字"
        sortable
        align="center"
      />
    </el-table>
  </div>
</template>

<script>
const dataName = ['涨', '车', '轴', '走', '周', '凤', '胡', '晶', '京', '梅', '韦', '小', '字', '陈', '程',
  '测', '就', '当', '费', '飞', '矿', '况', '李', '刘', '成', '龙', '于', '巷', '港', '翔']
const serviceArr = []
// service为模仿 服务端返回数据;具体数据你找后台;
const service = (param) => {
  const { pageNow, pageSize } = param
  const createData = (arr) => {
    const random = (number) => (Math.floor(Math.random() * number)).toFixed(0)
    const nameFn = () => Array.from(new Array(random(3) < 2 ? 2 : 3), () => dataName[random(dataName.length)]).join('')
    const data = Array.from(new Array(pageSize), (x, i) => nameFn()).map(name => ({ name }))
    arr.push(...data)
  }
  createData(serviceArr)
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        data: serviceArr.slice(pageSize * (pageNow - 1), pageSize * pageNow)
      })
    }, 500)
  })
}
export default {
  data() {
    return {
      tableData: [],
      loading: false,
      pageNow: 1,
      pageSize: 20
    }
  },
  created() {
    this.getList()
    this.$nextTick(() => this.addRollListener(() => this.scrollCallback()))
  },
  methods: {
    // 这个是获取列表信息的地方
    getList() {
      this.loading = true
      const param = {
        pageNow: this.pageNow,
        pageSize: this.pageSize
      }
      service(param).then(({ data }) => {
        this.tableData.push(...data)
        // .....
      }).finally(() => {
        this.loading = false
      })
    },
    // 这里是你写回调函数的地方(触发滚动)
    scrollCallback() {
      // ...
      console.log('触发滚动加载')
      this.pageNow++
      this.getList()
    },
    addRollListener(cb) {
      const dom = this.$refs.myTable.bodyWrapper
      dom.addEventListener('scroll', () => {
        const scrollTop = dom.scrollTop
        // 变量windowHeight是可视区的高度
        const windowHeight = dom.clientHeight || dom.clientHeight
        // 变量scrollHeight是滚动条的总高度
        const scrollHeight = dom.scrollHeight || dom.scrollHeight
        if (scrollTop + windowHeight + 1 > scrollHeight) cb && cb()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.element-table-scroll {
  height: 600px;
  display: flex;
}
</style>

2. 如果你的table被封成了组件;

  1. 如果你把上面的看过了;只需要在 a d d R o l l L i s t e n e r addRollListener addRollListener 函数中更改dom值;其他不变
  2. children[0]这个你去找找这个dom吧。万一不对就去找找吧。
  3. 逻辑就是通过 ref 获取子节点信息,然后在里面找你的 el-table
const dom = this.$refs.myTable.$children[0].bodyWrapper

以下为组件模式的示例代码

<template>
  <div class="element-table-scroll">
    <LhTable
      ref="myTable"
      :height="600"
      :table-config="tableConfig"
      :c-table-info="tableInfo"
      :pageination="false"
    />
  </div>
</template>

<script>
const dataName = ['涨', '车', '轴', '走', '周', '凤', '胡', '晶', '京', '梅', '韦', '小', '字', '陈', '程', '测', '就', '当', '费', '飞', '矿', '况', '李', '刘', '成', '龙', '于', '巷', '港', '翔']
const serviceArr = []
// service为模仿 服务端返回数据;具体数据你找后台;
const service = (param) => {
  const { pageNow, pageSize } = param
  const createData = (arr) => {
    const random = (number) => Math.floor(Math.random() * number).toFixed(0)
    const nameFn = () =>
      Array.from(
        new Array(random(3) < 2 ? 2 : 3),
        () => dataName[random(dataName.length)]
      ).join('')
    const data = Array.from(new Array(pageSize), (x, i) => nameFn()).map(
      (name) => ({ name })
    )
    arr.push(...data)
  }
  createData(serviceArr)
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({
        data: serviceArr.slice(pageSize * (pageNow - 1), pageSize * pageNow)
      })
    }, 500)
  })
}
import LhTable from './component/Table.vue'
export default {
  components: {
    LhTable
  },
  data() {
    return {
      tableConfig: [
        {
          label: '序号',
          type: 'index',
          width: '60px'
        },
        {
          label: '调取成功数量',
          prop: 'name'
        },
        {
          label: '调取成功设备占比',
          // h 等同与 vue 的 h 函数或者说 createElement 方法;规则等同;
          render: (h, { row }) => h('span', {}, row.name)
        }
      ],
      tableInfo: {
        tableData: [],
        loading: false
      },
      pageNow: 1,
      pageSize: 20
    }
  },
  created() {
    this.getList()
    this.$nextTick(() => this.addRollListener(() => this.scrollCallback()))
  },
  methods: {
    // 这个是获取列表信息的地方
    getList() {
      this.tableInfo.loading = true
      const param = {
        pageNow: this.pageNow,
        pageSize: this.pageSize
      }
      service(param)
        .then(({ data }) => {
          this.tableInfo.tableData.push(...data)
          console.log(this.tableInfo.tableData)
          // .....
        })
        .finally(() => {
          this.tableInfo.loading = false
        })
    },
    // 这里是你写回调函数的地方(触发滚动)
    scrollCallback() {
      // ...
      console.log('触发滚动加载')
      this.pageNow++
      this.getList()
    },
    addRollListener(cb) {
      // 重点就是去找组件的子集
      const dom = this.$refs.myTable.$children[0].bodyWrapper
      console.log(dom)
      dom.addEventListener('scroll', () => {
        const scrollTop = dom.scrollTop
        // 变量windowHeight是可视区的高度
        const windowHeight = dom.clientHeight || dom.clientHeight
        // 变量scrollHeight是滚动条的总高度
        const scrollHeight = dom.scrollHeight || dom.scrollHeight
        if (scrollTop + windowHeight + 1 > scrollHeight) cb && cb()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
.element-table-scroll {
  height: 600px;
  display: flex;
}
</style>

2.1 lh-table组件

scss不改样式,less则改为less,都没用直接删除style里面内容

<template>
  <div v-loading="loadings" class="lh-table">
    <el-table
      ref="table"
      border
      :class="['table-msg color-table ', className]"
      :stripe="stripe"
      :highlight-current-row="highlight"
      :size="size"
      :data="tableDataCheck"
      :max-height="height"
      :row-class-name="rowClassName"
      :style="{ height: pageination ? 'calc(100% - 60px)' : '100%' }"
      :span-method="spanMethod"
      @cell-dblclick="(param) => $emit('cell-dblclick', param)"
      @cell-click="(param) => $emit('cell-click', param)"
    >
      <el-table-column
        v-for="colConfig in tableConfig.filter(
          (item) => item.lhDisplay !== 'none'
        )"
        :key="colConfig['id']"
        v-bind="colConfig"
        align="center"
      >
        <template slot-scope="scope">
          <render
            v-if="colConfig.render"
            :key="colConfig['id']"
            :render="colConfig.render"
            :row="scope.row"
            :index="scope.$index"
            :column="colConfig"
          />
          <span v-else-if="colConfig.type === 'index'">{{
            scope.$index + 1
          }}</span>
          <span v-else>{{
            scope.row[colConfig && colConfig.prop] || "-"
          }}</span>
        </template>
      </el-table-column>
    </el-table>
    <!-- <LhPageination -->
    <el-pagination
      v-if="pageination"
      small
      background
      :page-size="pageSize"
      :page-sizes="pageSizes"
      :current-page="currentPage"
      :total="totalNum"
      @current-change="handleCurrentChange"
      @size-change="handleSizeChange"
    />
  </div>
</template>

<script>
// 只是把官网的这个组件源码拷贝下来 修改了一下里面的样式及布局;
// 使用这个 lh-table 这个组件 直接把LhPageination去掉然后用官网的就行了;
// import LhPageination from '@/components/anHui-new/lhPageination/index.js'

const pageination = {
  currentPage: 1,
  totalNum: 0,
  pageSize: 30,
  pageSizes: [10, 15, 20, 30, 50, 100]
}
const render = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null
    }
  },
  render: (h, data) => {
    const params = {
      row: data.props.row,
      index: data.props.index
    }
    if (data.props.column) params.column = data.props.column
    return data.props.render(h, params)
  }
}
export default {
  name: 'LhTable',
  components: {
    // LhPageination,
    render
  },
  props: {
    // table配置信息
    tableConfig: {
      type: Array,
      default: () => [
        {
          label: '序号',
          type: 'index',
          width: '80px'
        },
        {
          label: '名字',
          prop: 'name'
        },
        {
          label: '公司名称',
          prop: 'cmyName'
        }
      ]
    },
    // table的一些信息
    cTableInfo: {
      type: Object,
      default: () => ({
        // table的数据源
        tableData: [],
        // 是否开启加载等待
        loading: false
      })
    },
    // 分页配置
    cPageinationInfo: {
      type: Object,
      default: () => pageination
    },
    // 高度设置 具体参考官网的
    height: {
      type: Number,
      default: 250
    },
    // 是否显示分页器
    pageination: {
      type: Boolean,
      default: true
    },
    // 官网的
    size: {
      type: String,
      default: 'small'
    },
    // 官网的:highlight-current-row;高亮行
    highlight: {
      type: Boolean,
      default: true
    },
    // 给el-table添加class
    className: {
      type: String,
      default: ''
    },
    // 斑马条
    stripe: {
      type: Boolean,
      default: true
    },
    // 行样式回调函数  (官网的)
    rowClassName: {
      type: Function,
      default: () => {}
    },
    // 单元格合并回调函数(官网的)
    spanMethod: {
      type: Function,
      default: () => {}
    }
  },
  // 如果只有一个表格直接 provide/inject 多个表格则组件传参方式
  inject: {
    pageinationInfo: {
      default: () => ({
        lh_spe_flag: true
      })
    },
    tableInfo: {
      default: () => ({
        lh_spe_flag: true
      })
    }
  },
  data() {
    const { currentPage, totalNum, pageSize, pageSizes } = this.pageinationInfo.lh_spe_flag
      ? this.cPageinationInfo : this.pageinationInfo || pageination
    return {
      // pageLayout: pageLayout || [
      //   ['total', 'sizes'],
      //   ['prev', 'pager', 'next', 'jumper']
      // ],
      currentPage, // 当前页数
      totalNum, // 数据总条数
      pageSize, // 每页数据的条数
      pageSizes // 选择每页的条数
    }
  },
  computed: {
    loadings() {
      return this.tableInfo.lh_spe_flag
        ? this.cTableInfo.loading || false
        : (this.tableInfo && this.tableInfo.loading) || false
    },
    tableDataCheck() {
      return this.tableInfo.lh_spe_flag
        ? this.cTableInfo.tableData
        : this.tableInfo.tableData
    }
  },
  watch: {
    height(val) {
      console.log(val, 'val')
    },
    'pageinationInfo.totalNum'(n) {
      this.totalNum = n
    },
    'pageinationInfo.currentPage'(n) {
      this.currentPage = n
    }
  },
  methods: {
    handleCurrentChange(v) {
      console.log(1, v)
      this.$emit('current-change', v)
    },
    handleSizeChange(v) {
      this.$emit('size-change', v)
    }
  }
}
</script>

<style lang="scss" scoped>
.lh-table {
  position: relative;
  width: 100%;
  height: 100%;
  .table-msg {
    position: absolute;
  }
  .el-pagination {
    position: absolute;
    bottom: 0;
  }
  /deep/.el-table__body-wrapper {
    height: 100% !important;
    .el-table__empty-block {
      min-height: 10px !important;
    }
  }
}
</style>

效果图

element-ui的table实现滚动加载,涵el-table组件封装一份
element-ui的table实现滚动加载,涵el-table组件封装一份文章来源地址https://www.toymoban.com/news/detail-403097.html

到了这里,关于element-ui的table实现滚动加载,涵el-table组件封装一份的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue+element-ui el-table组件二次封装实现虚拟滚动,解决数据量大渲染DOM过多而卡顿问题

    某些页面不做分页时,当数据过多,会导致页面卡顿,甚至卡死 一、固定一个 可视区域 的大小并且其大小是不变的,那么要做到性能最大化就需要尽量少地渲染 DOM 元素,而这个最小值也就是可视范围内需要展示的内容,而可视区域之外的元素均可以不做渲染。 二、如何计

    2024年02月10日
    浏览(63)
  • element-ui的树形表格el-table懒加载lazy子节点修改数据后局部刷新

    在使用element-ui的树形表格(el-table)懒加载(lazy),并使用了懒加载,出现了一个问题,在对当前节点添加、修改、删除一个子节点数据时,当前节点的子节点数据并不自动刷新出来。element-ui官方没有提供子节点修改数据后局部刷新方法。 首先,在data(){}中定义一个maps:new Map();

    2024年02月12日
    浏览(45)
  • element-ui el-table 如何实现合并单元格

    el-table的组件的可以合并单元格,先定义参数span-method 方法objectSpanMethod。在方法内控制当前单元格渲染成几个单元格或者删除掉当前单元格。 比如:代码中定义:span-method=\\\"objectSpanMethod\\\" objectSpanMethod实现是在方法区,具体内容是根据变量rowSpanList 去决定当前单元格是展示还是删

    2024年02月03日
    浏览(45)
  • element-ui中的el-table实现分页多选功能

    selection-change事件:当选择项发生变化时会触发该事件(当分页切换时,选中的数据都会自动清空) 链接: https://blog.csdn.net/qq_36157085/article/details/122922678

    2024年02月17日
    浏览(44)
  • Element-ui中表格el-table图片预览效果实现(非常实用)

    🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅  文末获取源码联系 🏆先展示效果:   🏆使用的是下面这个插

    2024年02月11日
    浏览(56)
  • 随手记:使用sortable.js 实现element-ui el-table 表格上下拖拽排序

    需求场景: 表格可以实现上下拖拽row实现新排序 首先,安装sortable.js  引入表格排  全局挂在组件 使用页面引入 使用sortable.js表格一定要有唯一的row-key,一般绑定的是id,不然拖拽会不生效 data声明 sortableContainer: null,为的是后面如果有需要可以做销毁操作   因为我这里是表

    2024年02月22日
    浏览(52)
  • 【性能优化】虚拟懒加载(下拉滚动加载长列表)element-puls+el-table

    提示:这里可以添加本文要记录的大概内容: 在element-plus中,如果数据超过1k,就会感觉到明显的卡顿,应该是渲染的卡顿吧。反正我在请求回来接口之后,loading,会卡顿。用户体验十分不佳。然后吧,这个列表还不能分页,得全部展示出来,因为设计的,不能改,上面要求

    2024年02月07日
    浏览(42)
  • [element-ui] el-table点击高亮当前行

    1、highlight-current-row 2、:row-class-name=“tableRowClassName”,需要借助@row-click=\\\"handleRowClick\\\"获取当前点击行的下标 参考: elementUI中table点击高亮当前行的两种方式

    2024年03月21日
    浏览(47)
  • element-ui中的el-table合并单元格

    在写项目的时候有时候会经常遇到把行和列合并起来的情况,因为有些数据是重复渲染的,不合并行列会使表格看起来非常的混乱,如下:  而我们想要的数据是下面这种情况,将重复的行进行合并,使表格看起来简单明了,如下:   1:html部分 所谓的合并行就是将多行相同

    2024年02月10日
    浏览(42)
  • Vue+Element-UI 实现前端分页功能,利用el-table和el-pagination组件实现表格前端分页

    Vue+Element-UI 实现前端分页功能,利用el-table和el-pagination组件实现表格前端分页:         当table的数据量比较大的时候,一个屏幕展示不出全部的数据,这个时候就需要分页显示。而多数情况下都是做的后端分页,就是将分页参数和查询条件一并传到后端,后端将当前页要

    2024年01月20日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包