资讯专栏INFORMATION COLUMN

iView之Select组件的优化

jsbintask / 429人阅读

摘要:接下来本文会对比组件在性能上做出的优化。出现该问题的原因在组件的钩子中有三个监听,分别是组件添加,删除,和选中时监听事件。在监听事件中会去遍历当中的所有子组件做出相应的改变。

iViewSelect组件在性能上的优化

    我们公司的组件库是基于iView 比较早的版本修改后的仅供公司内部使用的组件库,因此在使用的过程中就会遇到一些问题。接下来本文会对比Select组件在性能上做出的优化。

Debounce函数

    我们先来回顾一下debounce函数的使用场景:在前端页面我们会遇到一些频繁触发的事件;比如

鼠标的移动mousemove事件;

window对象的resizescroll事件;

keydown,keyup事件;

实际的使用过程中我们可能不需要每次触发事件的时候都去响应该事件,我们往往需要当用户停止操作多少ms后去响应事件。这个时候我们就需要用到debounce函数了。下面是一段debounce函数

export function debounce(fn) {
    let waiting;
    return function() {
        if (waiting) return;
        waiting = true;
        const context = this,
            args = arguments;
        const later = function() {
            waiting = false;
            fn.apply(context, args);
        };
        this.$nextTick(later);
    };
}

这段代码的意思的意思是当DOM更新后去响应这个事件,并且DOM更新后只会执行一次
有了这些知识的准备我们就可以来谈谈使用这个组件遇到的性能问题了。

低版本iviewSelect组件遇到的问题

    在使用低版本的组件过程中,当数据量很大例如某个select选择器里面有500条甚至更多的数据时,进行模糊搜索有可能卡死页面,关闭页面有延迟。

出现该问题的原因

    在Select组件的mounted钩子中有三个监听,分别是组件添加,删除,和选中时监听事件。在监听事件中会去遍历Select当中的所有子组件做出相应的改变。

//监听子组件的移除
this.$on("remove",() => {
    if (!this.remote) {
        this.modelToQuery();
        this.$nextTick(() => this.broadcastQuery(""));
    } else {
        this.findChild((child) => {
            child.updateSearchLabel();   // #1865
            child.selected = this.multiple ? this.model.indexOf(child.value) > -1 : this.model === child.value;
        });
    }
    this.slotChange();
    this.updateOptions(true);
})

查找这个监听的通知对象发现正是Select的子组件在销毁或者是创建时通知父组件做出相应的变化。

//组件销毁时通知父组件
beforeDestroy () {
    this.dispatch("iSelect", "remove");
    this.$off("on-select-close", this.onSelectClose);
    this.$off("on-query-change",this.onQueryChange);
}

那么问题就出在这里了,当有大量的子组件时,每一个组件移除,父组件需要遍历一次。这样就拖累性能。

解决办法

    既然前面提到debounce函数,想必大家应该想到要怎么解决了。使用debounce函数能够解决这个问题,我们只需要所有子组件销毁时通知父组件一次就够了。引入debounce函数后经本人测试基本上解决了卡顿以及卡死的问题,代码如下。

//select组件mounted函数当中去监听 append 、remove 事件
this.$on("append", this.debouncedAppendRemove());
this.$on("remove", this.debouncedAppendRemove());
//引入debounce函数
debouncedAppendRemove(){
    return debounce(function(){
        if (!this.remote) {
            this.modelToQuery();
            this.$nextTick(() => this.broadcastQuery(""));
        } else {
            this.findChild((child) => {
                child.updateSearchLabel();   // #1865
                child.selected = this.multiple ? this.model.indexOf(child.value) > -1 : this.model === child.value;
            });
        }
        this.slotChange();
        this.updateOptions(true);
    });
}
其他细节

    低版本中子组件的监听事件没有移除掉,高版本的有移除。

mounted () {
    this.$on("on-select-close", this.onSelectClose);
    this.$on("on-query-change",this.onQueryChange);
}

beforeDestroy () {
    this.$off("on-select-close", this.onSelectClose);
    this.$off("on-query-change",this.onQueryChange);
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/94586.html

相关文章

  • VUE UI框架对比 element-ui 与 iView

    摘要:而则是用到到指令结合的方式去生成,批量生成元素。表格操作列自定义渲染的时,使用的是的函数,直接在中插入对应模板表格分页都需要引入分页组件配合使用两者总体比较,要比简洁许多。 element VS iview(最近项目UI框架在选型 ,做了个分析, 不带有任何利益相关)主要从以下几个方面来做对比使用率(npm 平均下载频率,组件数量,star, issue…)API风格打包优化与设计师友...

    ZHAO_ 评论0 收藏0
  • Vue高效UI组件库—iView开发实践

    摘要:它的文档也是相当详细,每个功能都配有详细说明和实例代码,直接复制就可以使用,我们也计划在明年启动英文文档翻译计划。明年会启动英文文档翻译计划,也希望喜欢和支持,同时英语不错的同学可以加入我们,一起参与翻译。 前段时间在微软参加活动,分享了 TalkingData 开源的基于 Vue.js 的高效 UI 组件库 iView 的一些开发经验,现整理成文,和大家探讨。 showImg(htt...

    wean 评论0 收藏0
  • iView 近期更新,以及那些“不为人知”故事

    摘要:如图所示还有其它很多项的更新,比如新增属性,可以设置面板展开时默认显示的日期。目前最新版本支持键盘可访问性的组件有。期待你的加入下个版本预告下个版本计划重构组件,以全面支持表单组件的键盘可访问性,敬请期待。 在过去的两个多月里,iView 陆续发布了 2.9.0 和 2.10.0 两个重要版本。这两个版本总共有 255 个 commit,超过 40 项更新。来看一下,iView 具体都...

    UsherChen 评论0 收藏0
  • iView 发布 3.0 版本,以及开发者社区等 5 款新产品

    摘要:相对时间组件锚点组件面板分割组件分割线组件单元格组件相对时间组件用于表示几分钟前几小时前等相对于此时此刻的时间描述。单元格组件在手机上比较常见,在上则常用于固定的侧边菜单项。开发者社区这是发布会最劲爆的一款产品了。 showImg(https://segmentfault.com/img/bVbeuj6?w=2864&h=1458); 7 月 28 日,我们成功地召开了 iView 3...

    FreeZinG 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<