vue+el-table实现鼠标滚动加载接口大量数据

          <el-table
            ref="xxTable"
            :data="viewZoneData"
          >
            <el-table-column type="index" label="序号" width="50" align="center" />
            </el-table-column>
          </el-table>
          <div v-if="showLoad" class="load-box"><i class="el-icon-loading" />&nbsp;&nbsp;加载中</div>
<script>
import { debounce } from '@/common/debounce'
  data() {
    return {
      tableList: [], // 接口拿带大量数据后传递给这个变量!!!
      originData: [],
      viewZoneData: [],
      isNeedLoad: false, // 是否需要进行加载操作
      cutIndex: 0,
      showLoad: false
    }
  },
  mounted() {
    window.addEventListener('scroll', this.loadData, true)
  },
  beforeDestroy() {
    window.removeEventListener('scroll', this.loadData, true)
  },
  watch: {
    tableList(val) {
      this.originData = common.deepCopy(val)
      if (this.originData.length >= 20) {
        this.isNeedLoad= true
        this.viewZoneData= this.originData.slice(0, 20)
        this.cutIndex = 20
      } else {
        this.isNeedLoad= false
        this.viewZoneData= this.originData
      }
    }
  },
  methods: {
    // 加载数据
    loadData: debounce(function() {
      if (this.isNeedLoad) { // 需要分段加载才触发以下代码
        const offsetHeight = this.$refs.xxTable.$el.offsetHeight
        const scrollTop = this.$refs.xxTable.bodyWrapper.scrollTop // 一直都是0
        const scrollHeight = this.$refs.xxTable.bodyWrapper.scrollHeight
        let loadMore = offsetHeight + scrollTop + 50 >= scrollHeight
        if (loadMore) {
          loadMore = false
          this.showLoad = true
          const newData = this.originData.slice(this.cutIndex, this.cutIndex += 20)
          this.viewZoneData.splice(this.cutIndex, 0, ...newData)
          this.$nextTick(() => {
            this.showLoad = false
          })
        }
      }
    }, 150, false), //当滚动条触底时,150ms后加载下一分段数据,可根据需求调整速率
    httpRequest: function(item) {
	      this.name = item.file.name
	      const file = item.file
	      const fd = new FormData()
	      fd.append('file', file)
	      API.deliverImportAPI(fd).then(res => {
	        if (res.data.flag === 'success') {
	          const importData = res.data.data // 导入的数据
	          this.tableList = []
	          this.tableList = importData
	          this.$successMsg('导入文件完成')
	        } else {
	          this.$errorMsg(res)
	        }
	      }).catch(() => {
	      })
    },
  }

debounce.js

/**
* 防抖函数
* @param func 用户传入的防抖函数
* @param wait 等待的时间
* @param immediate 是否立即执行
*/
export const debounce = function(func, wait = 50, immediate = false) {
  // 缓存一个定时器id
  let timer = null
  let result
  const debounced = function(...args) {
    // 如果已经设定过定时器了就清空上一次的定时器
    if (timer) {
      clearTimeout(timer)
    }
    if (immediate) {
      const callNow = !timer
      // 等待wait的时间间隔后,timer为null的时候,函数才可以继续执行
      timer = setTimeout(() => {
        timer = null
      }, wait)
      // 未执行过,执行
      if (callNow) result = func.apply(this, args)
    } else {
      // 开始一个定时器,延迟执行用户传入的方法
      timer = setTimeout(() => {
        // 将实际的this和参数传入用户实际调用的函数
        func.apply(this, args)
      }, wait)
    }
    return result
  }
  debounced.cancel = function() {
    clearTimeout(timer)
    timer = null
  }
  // 这里返回的函数时每次用户实际调用的防抖函数
  return debounced
}

common.js


/*
 * @Author: xxx
 * @Descripttion: 深拷贝
 * @Date: 2021.xx.xx
 */
function typeOf(obj) {
  const toString = Object.prototype.toString
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object'
  }
  return map[toString.call(obj)]
}

function deepCopy(data) {
  const t = typeOf(data)
  let o

  if (t === 'array') {
    o = []
  } else if (t === 'object') {
    o = {}
  } else {
    return data
  }

  if (t === 'array') {
    for (let i = 0; i < data.length; i++) {
      o.push(deepCopy(data[i]))
    }
  } else if (t === 'object') {
    for (const i in data) {
      o[i] = deepCopy(data[i])
    }
  }
  return o
}


export default {
  deepCopy
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您可以通过在 `el-table` 中使用 `el-input-number` 组件来实现购物车功能。以下是一个简单的示例代码: 首先,需要在组件中引入所需的组件: ```vue <template> <div> <el-table :data="cartData" style="width: 100%"> <el-table-column prop="name" label="商品名称"></el-table-column> <el-table-column prop="quantity" label="数量"> <template slot-scope="scope"> <el-input-number v-model="scope.row.quantity" @change="updateTotalPrice"></el-input-number> </template> </el-table-column> <el-table-column prop="price" label="单价"></el-table-column> <el-table-column prop="totalPrice" label="总价"></el-table-column> </el-table> </div> </template> <script> export default { data() { return { cartData: [ { name: '商品1', quantity: 1, price: 10, totalPrice: 10 }, { name: '商品2', quantity: 2, price: 20, totalPrice: 40 }, { name: '商品3', quantity: 3, price: 30, totalPrice: 90 } ] }; }, methods: { updateTotalPrice() { this.cartData.forEach(item => { item.totalPrice = item.quantity * item.price; }); } } }; </script> ``` 在上述代码中,`cartData` 数组是购物车中的数据源,包含商品名称、数量、单价和总价等信息。在 `el-table` 中的 `el-table-column` 中,使用 `el-input-number` 组件来编辑商品的数量,并通过 `v-model` 绑定到 `cartData` 数组中的 `quantity` 属性上。当数量发生变化时,通过 `@change` 事件触发 `updateTotalPrice` 方法,更新对应商品的总价。 注意:以上代码仅为示例,实际应用中,您可能需要从后端动态获取购物车数据,并与后端进行交互来更新购物车信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值