赞
踩
技术栈
- Vue.js
- ElementUi
无限滚动优点
解决dom一次性渲染开销大, 导致浏览器卡顿, 或者内存不足崩溃
无限滚动缺点:
理论上无限滚动数据量达到w级也会逐步开始卡顿, 暂时还没尝试过
针对vue框架做了directive(自定义指令 — Vue.js)的形式开发, 代码如下
- // src/directive/lazyLoading.js
- function debounce(fn, delay) {
- // 防抖
- var timeout = null; // 创建一个标记用来存放定时器的返回值
- return (e) => {
- clearTimeout(timeout); // 每当用户输入的时候把前一个 setTimeout clear 掉
- // 然后又创建一个新的 setTimeout, 这样就能保证interval 间隔内如果时间持续触发,就不会执行 fn 函数
- timeout = setTimeout(() => {
- fn.apply(this, arguments);
- }, delay);
- };
- }
-
- export default {
- install(Vue) {
- Vue.directive("lazyLoading", {
- bind(el, binding) {
- const { value } = binding;
- let elementClass = null;
- let lazyFun = null;
- if (typeof value == "object") {
- const { elementClass: _elementClass, lazyFun: _lazyFun } = value; // elementClass 滚动盒子的class, lazyFun 调用的函数
- elementClass = _elementClass;
- lazyFun = _lazyFun;
- } else if (typeof value == "function") {
- lazyFun = value;
- } else {
- console.err("传参错误");
- return;
- }
- // 获取element-ui定义好的scroll盒子
- const SELECTWRAP_DOM = el.querySelector("." + elementClass);
- SELECTWRAP_DOM.addEventListener("scroll", function () {
- let { clientHeight, scrollTop, scrollHeight } = this;
- // 当用户的滚动距离大于等于滚动条的总高度, 就执行lazyFun方法
- const CONDITION = Math.ceil(clientHeight + scrollTop) >= scrollHeight;
- if (CONDITION) {
- debounce(lazyFun(), 300);
- }
- });
- },
- });
- },
- };
- // src/main.js 在入口文件引入, vue实例生成前调用
- import lazyLoading from "@/directive/lazyLoading";
- Vue.use(lazyLoading);
-
- new Vue({
- el: "#app",
- ...
- });
- // 页面使用
- <el-scrollbar
- v-lazy-loading="{
- lazyFun: lazyFun,
- elementClass: 'el-scrollbar__wrap',
- }"
- >
- ...
- </el-scrollbar>
-
- <script>
- export default {
- data() {
- return {
- renderNum: 0, //渲染次数
- renderList: [], //渲染的数据
- };
- },
- methods: {
- // 初始化懒加载数据 从0开始
- initLazyFun() {
- let count = 5;
- this.renderList = this.upList.slice(0, count);
- this.renderNum += count;
- },
- // 更新当前懒加载数据 仅更新renderNum数量, 不继续+count
- updateLazyFun() {
- this.renderList = this.upList.slice(0, this.renderNum);
- },
- // 懒加载数据
- lazyFun() {
- let count = 5;
- this.renderList = this.upList.slice(0, this.renderNum + count);
- this.renderNum += count;
- },
- };
- </script>
自定义指令拓展
指令钩子函数会被传入以下参数:
el
:指令所绑定的元素,可以用来直接操作 DOM。binding
:一个对象,包含以下 property:
name
:指令名,不包括 v-
前缀。value
:指令的绑定值,例如:v-my-directive="1 + 1"
中,绑定值为 2
。oldValue
:指令绑定的前一个值,仅在 update
和 componentUpdated
钩子中可用。无论值是否改变都可用。expression
:字符串形式的指令表达式。例如 v-my-directive="1 + 1"
中,表达式为 "1 + 1"
。arg
:传给指令的参数,可选。例如 v-my-directive:foo
中,参数为 "foo"
。modifiers
:一个包含修饰符的对象。例如:v-my-directive.foo.bar
中,修饰符对象为 { foo: true, bar: true }
。vnode
:Vue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。oldVnode
:上一个虚拟节点,仅在 update
和 componentUpdated
钩子中可用。文章参考
vue2.0 自定义指令 ++ element-ui 自定义el-select的下拉懒加载指令 - 灰信网(软件开发博客聚合)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。