vue如何实现el-select下拉选项的懒加载

目录
  • 滚动加载的核心逻辑
  • 在vue中处理数据懒加载
  • 在vue组件中使用指令 v-lazy-load
  • Element 指令v-infinite-scroll

下拉选择是常用的用户交互选择的操作;常用固定选择项或者动态渲染选择项。

实际项目中存在数据量大,一次性渲染很多数据会造成下拉卡顿的问题,通过滚动懒加载,逐步增加下拉选项。

滚动加载的核心逻辑

通过监听容器的滚动事件,滚到最底部时,执行加载数据函数。

interface IScrollOption {
  distance: number; // 触发loadData事件的滚轴距底部的距离
  loadData: () => void; // 数据加载函数
}
/**
 * 处理容器滚动事件 ; 滚动到底部时,执行处理函数
 * @param dom
 * @param option
 */
function handleScroll(dom: Element, option: IScrollOption) {
  //
  const scrollBottom = dom.scrollTop + dom.clientHeight;
  if (dom.scrollHeight - scrollBottom <= option.distance) {
    // 数据加载
    option.loadData();
  }
}

在vue中处理数据懒加载

使用Element作为UI组件,常用下拉select 方式为

<el-select v-model="selectData">
  <el-option v-for="item in data" :key="item.id" value="item.id" :label="item.name"></el-option>
</el-select>

data 为渲染数据,存在大批量数据时,防止下拉卡顿,采用懒加载的方式逐步增加数据

由于el-select 组件并没有提供内部数据滚动的事件或者自定义内部滚动容器DOM元素 . 只能通过F12 查看页面结构获知滚动的容器DOM选择器 .

可以通过自定义指令的方式,提取共用逻辑,不局限于select,也可用于其他列表懒加载渲染的UI组件.

/**
 * 定义懒加载数据列表的指令
 * 可通过滚动懒加载来减少一次性渲染大量数据的性能卡顿
 */
import Vue from "vue";
import { throttle } from "lodash";
export interface ILazyProps {
  loadData: () => void; // 数据加载函数
  distance: number; // 触发函数调用的滚动距离
  scrollBody?: string; // 置顶滚动容器 , 不指定则为指令绑定元素
  callback: (fn: () => void) => void; // 自定义回调逻辑,可用于适时销毁监听事件
}
Vue.directive("lazy-load", {
  /**
   * el - 指令所绑定的元素DOM
   * binding - 传入指令的其他附带参数
   *    name - 指令名
   *    value  - 指令绑定的值
   *    oldValue - 绑定的前一个值
   *    expression - 指令绑定的字符串形式的表达式
   *    arg - 传给指令的参数
   *    modifiers - 指令修饰符的对象
   * vnode
   * oldVnode
   */
  inserted: (el, binding) => {
    // 获取scroll 滚动的容器元素,由参数传入
    // 如果没有传入,则默认绑定指令的元素自己
    // 获取懒加载处理函数 , 以及其他参数
    const { loadData, distance, scrollBody, callback } =
      binding.value as ILazyProps;
    let scrollContainer = el;
    if (scrollBody) {
      scrollContainer = el.querySelector(scrollBody) || el;
    }
    // 滚动事件监听
    const scroll = throttle(
      handleScroll.bind(null, scrollContainer, { distance, loadData }),
      500
    );
    scrollContainer.addEventListener("scroll", scroll);
    // 回调时 返回事件销毁函数
    callback(() => {
      scrollContainer.removeEventListener("scroll", scroll);
    });
  },
});

在vue组件中使用指令 v-lazy-load

视图,只需要添加指令.绑定指令需要的属性值.

<el-select v-model="selectData" v-lazy-load="lazyOption">
  <el-option v-for="item in data" :key="item.id" value="item.id" :label="item.name"></el-option>
</el-select>

脚本部分 , 包括初始化layzOption 定义数据加载函数

import { ILazyProps } from "@/directives/lazyLoad";
export default class extends Vue {
  lazyOption: ILazyProps = {
    loadData: this.loadData,
    distance: 20,
    scrollBody: ".el-scrollbar__wrap", // 为el-select 滚动容器的DOM元素的class选择器
    callback: (fn: () => void) => {
    	// 这里是在组件销毁前, 移除监听事件.
      this.$once("hook:beforeDestroy", () => fn());
    },
  };
	loadData(): void {
    this.data = this.data.concat(
      new Array(5).fill({
        id: "1009",
        name: "双十一",
      })
    );
  }
}

Element-plus 正在新增的一个组件 el-select-v2 虚拟化列表下拉选择器 . 虚拟列表与懒加载不同的是,虚拟列表渲染的DOM节点固定,通过滚动的位置计算需要展示的数据.

Element 指令v-infinite-scroll

element 也提供了用于懒加载数据的指令v-infinite-scroll , 缺陷在于它只监听指令绑定的DOM元素的滚动事件.

  • infinite-scroll-disabled 是否禁用加载,如果是分页数据 , 则可以通过计算属性pageSize*pageNum>=total
  • infinite-scroll-delay 节流加载,默认 200ms
  • infinite-scroll-distance 触发加载的滚动距离阀值 .
  • infinite-scroll-immediate 是否立即执行加载函数,需要撑满容器元素;否则手动请求一次数据.

整个数据列表页不需要分页操作时, 需要通过页面滚动来加载数据

<div v-infinite-scroll="loadData" infinite-scroll-disabled="disabled" infinite-scroll-delay="delay">
    <table
      :showPagination="false"
      :tableOption="tableOption"
      :tableColumns="tableColumns"
    ></table>
</div>

页面滚动时调用loadData函数,定义请求加载数据的逻辑.

直接贴源码

export default {
  name: 'InfiniteScroll',
  inserted(el, binding, vnode) {
    // 绑定的回调函数
    const cb = binding.value;
		// 当前组件实例引用
    const vm = vnode.context;
    // only include vertical scroll
    // 滚动容器DOM元素
    const container = getScrollContainer(el, true);
    // 获取指令需要的参数 delay distance immediate disabled
    const { delay, immediate } = getScrollOptions(el, vm);
    // 滚动事件处理函数,节流
    const onScroll = throttle(delay, handleScroll.bind(el, cb));
		// 将额外的计算属性绑定到el上,在unbind 可用于移除监听函数
    el[scope] = { el, vm, container, onScroll };
    if (container) {
      container.addEventListener('scroll', onScroll);
      if (immediate) {
        // 容器内元素发生节点变更时触发执行
        // MutationObserver API 功能调用
        const observer = el[scope].observer = new MutationObserver(onScroll);
        observer.observe(container, { childList: true, subtree: true });
        // 初始调用一次滚动加载函数
        onScroll();
      }
    }
  },
  unbind(el) {
    // 移除滚动事件
    const { container, onScroll } = el[scope];
    if (container) {
      container.removeEventListener('scroll', onScroll);
    }
  }
};
  • MutationObserver 监视对DOM树更改的能力

实例构造函数接收一个回调函数,为DOM发生变化时需要执行的回调

  • observe(target,[option]) 配置需要监听的DOM元素,以及DOM变更的配置项
  • disconnect() 停止接收DOM变化的通知
  • takeRecords() 获取未被回调处理的通知

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • el-select数据过多懒加载的解决(loadmore)

    el-select数据过多处理方式 在日常项目中el-select组件的使用频率是非常之高的. 当数据过多时渲染时间非常长, 这里提供几个处理方式. 远程搜索 组件提供了远程搜索方式, 也就是按照你输入的结果匹配选项. 下拉懒加载loadMore 下拉懒加载, 当select滚动到底部时, 你再去请求一部分数据, 加入到当前数据中. 某组件中: <template> <el-select v-model="value" placeholder="请选择&qu

  • el-select 下拉框多选实现全选的实现

    在写一个功能时发现el-select支持多选,但是竟然不支持全选,好无语哦,那就自己实现一下吧~有两种方法,第二种感觉简单些 方法一:下拉项增加一个[全选],然后应该有以下几种情况: 下拉选项全都勾选时,[全选]自动勾选: 下拉选项部分勾选时,点击[全选]后,所有下拉项全部勾选: 下拉选项全都未勾选时,点击[全选]后,所有下拉选项不勾选: 下拉选项和[全选]都选上的时候,不勾选任意下拉选项,[全选]按钮就不勾选了: 上面就是我要实现的功能,我好啰嗦...还是看代码吧... html部分: <te

  • vue+element树组件 实现树懒加载的过程详解

    一.页面样式 二.数据库 三.前端页面代码 <template> <el-tree :props="props" :load="loadNode" lazy show-checkbox> </el-tree> </template> <script> export default { data () { return { props: { label: 'name', children: 'zones',

  • Vue中el-form标签中的自定义el-select下拉框标签功能

    页面写死el-select下拉框标签: 通过v-for="item in stateArr"绑定,stateArr声明在Vue组件里面的data参数里面代码如下: 到此这篇关于Vue中el-form标签中的自定义el-select下拉框标签功能的文章就介绍到这了,更多相关Vue el-form标签 自定义el-select下拉框标签内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

  • vue如何实现el-select下拉选项的懒加载

    目录 滚动加载的核心逻辑 在vue中处理数据懒加载 在vue组件中使用指令 v-lazy-load Element 指令v-infinite-scroll 下拉选择是常用的用户交互选择的操作:常用固定选择项或者动态渲染选择项. 实际项目中存在数据量大,一次性渲染很多数据会造成下拉卡顿的问题,通过滚动懒加载,逐步增加下拉选项. 滚动加载的核心逻辑 通过监听容器的滚动事件,滚到最底部时,执行加载数据函数. interface IScrollOption { distance: number; //

  • 在element-ui的select下拉框加上滚动加载

    在项目中,我们需要运用到很多来自后端返回的数据.有时是上百条,有时甚至上千条.如果加上后端的多表查询或者数据量过大,这就导致在前端的显示就会及其慢,特别是在网络不好的时候更是如此. 自然,后端就做了一项非常"漂亮"的交互体验数据--分页 这不分页还好,一分页对超过10条数据之后的本来也不多,就20条,偏偏还得做个分页器.(假设为10条) 此时,如果能够像购物商城那样拖拽到底部自动加载新数据就好了. 于是<在element-ui的select下拉框加上滚动加载>诞生了. 这里

  • 微信小程序自定义select下拉选项框组件的实现代码

    知识点:组件,animation,获取当前点击元素的索引与内容 微信小程序中没有select下拉选项框,所以只有自定义.自定义的话,可以选择模板的方式,也可以选择组件的方式来创建. 这次我选择了组件,这样只需引入组件和添加数据,其它的不用管,就能实现多个地方重复使用了. 第一步:创建组件所需的文件 我喜欢把共用的内容都放在和pages文件同级的地方,所以有了下面的目录结构 (1) 先创建一个自定义名字的文件夹,例如我上面的Componet (2) 再创建一个select文件夹,然后:右键这个文件

  • 微信小程序自定义select下拉选项框的方法

    本文实例为大家分享了微信小程序自定义select下拉选项框的具体代码,供大家参考,具体内容如下 第一步:创建组件所需的文件 第二步:开始配置组件 select.json {   "component": true,   "usingComponents": {     "select": "./select"   } } 第三步:自定义组件样式及js select.wxml <view class='com-select

  • vue移动端下拉刷新和上滑加载

    本文实例为大家分享了vue移动端下拉刷新和上滑加载的具体代码,供大家参考,具体内容如下 组件 <template> <div class="mu-load-more" @touchstart="touchStart($event)" @touchmove="touchMove($event)" @touchend="touchEnd($event)"> <div class="mu-re

  • 基于iScroll实现下拉刷新和上滑加载效果

    本文实例为大家分享了iScroll下拉刷新上滑加载展示的具体代码,供大家参考,具体内容如下 html代码: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=devi

  • 关于layui的下拉搜索框异步加载数据的解决方法

    思路分析:当我使用layui默认的下拉搜索框的时候,layui会默认渲染出一个HTML结构,所以我把渲染出来的这个结果直接给复制出来,这样css的样式就不用从头到尾写一遍了, 前端代码(我用的是jsp): <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC &quo

  • Android手把手教大家制作APP首页(下拉刷新、自动加载)

    一.概述 作为一名三年Android开发经验的程序员,今天和大家一起实战一款APP的首页功能,这个首页在我们平时接触中还是很常见的,虽然页面简单,但是里面涉及的功能点还是挺多的.代码如有不足的还望各路同仁指点一二. 页面中使用的开发库: 整个首页架构使用的是LRecyclerView,包含下拉刷新和自动加载功能 compile 'com.github.jdsjlzx:LRecyclerView:1.3.3' 无限循环轮播图使用的是convenientbanner,效果还是很顺畅的,还可以根据自己

  • Flutter 给列表增加下拉刷新和上滑加载更多功能

    有状态组件 当 Flutter 的页面需要动态更新数据的时候,就会涉及到 UI 组件需要根据数据变化更新,此时也就意味着组件有了"状态".这就类似 React 的类组件和函数组件(只是后续 React 使用了勾子函数实现了函数组件也可以有状态).在 Flutter 中,组件也分为无状态组件(StatelessWidget)和有状态组件(StatefulWidget),一般尽量使用无状态组件.但是如果组件本身需要维护自身状态的时候,就需要使用有状态组件了.有状态组件的定义形式如下: //

  • Android仿XListView支持下拉刷新和上划加载更多的自定义RecyclerView

    首先给大家展示下效果图,感觉还不错,请继续往下阅读: 下拉刷新:        上划加载        在项目更新的过程中,遇到了一个将XListView换成recyclerView的需求,而且更换完之后大体效果不能变,但是对于下拉刷新这样的效果,谷歌给出的解决方案是把RecyclerView放在一个SwipeRefreshLayout中,但是这样其实是拉下一个小圆形控件实现的,和XListView的header效果不同.在网上找了很多的别人代码,都没有实现我想要的效果,于是自己动手写了一个.

随机推荐