使用虚拟dom,优化长列表显示(下)
[视频] 现在我们开始代码演示。使用recycle-view组件,首先需要在我们文档管理器里面选择miniprogram目录,然后选择它的在内建终端中打开,打开我们内建终端界面,在这个地方。 当前这个目录就是我们的小程序的所在的目录,第一步我们需要安装我们刚才提到的组件对吧,我们可以用yarn add然后去安装。它的名字是miniprogram-recycle-view这是它的名字,然后回车,安装以后我们可以看到一共是有一个文件,这个文件package.json生成了对吧,里面有一个dependencies里面多了一个组件,后面是它的一个版本号。然后在这个上面还多了一个node_moduels这样的一个目录。在这个目录下面我们可以看到也多出来了这样的一个组件,这是我们从外网下载下来的。通过这个指令下载的组件这是一步,这一步搞完以后我们还需要做个事情是什么? 在使用之前需要做的就是选择菜单工具,然后再选择这个构建npm。构建完成以后会再生成一个叫做miniprogram_npm这样的一个组件,这个组件才是我们这个小程序在运行的时候真正要加载模块的一个目录。它本质上代码是从这里加载的,它为啥要做这一步?是因为我们原来的默认加载下来的,下载下来组件的源码它有很多冗余的部分,有source代码、有目标代码。本质上我们运行时我们只需要这个目标代码,所以它就有了这一步。把这个目标代码拷贝到这个地方来,如果不这样做的话,这个代码包因为加了很多多余的一些其他代码,代码包体积会变大很多,这也是一个优化措施。 这一步,然后安装。安装完了以后接下来我们就可以去添加我们的组件了。在我们的主页里面我们看一下,首先是引用,要将我们的代码,我们打一个using,它会有提示的。我们可以使用这个具体这个代码的一个引用,就是引用我们已经放在目录下的组件,使用这个在我这里最终源码里面。我们2.2就是我们本节的最终源码,这个里面已经有写好的一个代码。我们将这个代码为了节省时间,我们直接把它给拷贝过来使用,实际上你在实践的时候自己亲自手写也是可以的,也没有问题。 这是组件的引用,接下来引用完成以后,我们要去改写我们的页面代码。页面代码首先是外围的recycle-view的一个使用,这是最外围,我们可以将使用它代替我们的这个地方,最外围的一个view,把这个给它代替。然后前后要对称,这个也给它改掉也是recycle-view。接下来就是里边我们的这两个slot也需要保留,一个是after一个是before。这个就是after,然后再往里面就是我们recycle-item的一个使用。这地方有一个block,将使用我们recycle-item代替block。原来循环的列表对象是allList,现在不需要了,现在要改成它里边我们用到的这些数据的一些绑定。这些都不需要变化,包括这个绑定也不需要变化,这是我们在单击某一项列表元素的时候去触发的,然后这个里面我们会有一个onScroll,这是我们新添加的一个事件监听,它是在我们这个列表滚动的时候触发的。 onScroll这个事件回调函数,它的源码很简单,我们目前只是让它有一个打印,告诉我们这个列表正在滚动,其他的我们暂时不需要。 这是关于wxml代码的一个修改,接下来我们开始改造我们JS代码。JS代码首先第一步是干嘛?需要引用、需要引入,将组件里边导出的这个方法引入。这个地方我们提一下,我们用require引入模块的时候,因为我们这个模块它本身就位于我们miniprogram_npm这个目录下面,所以我们这个地方可以直接使用这个名字去加载,不需要去写这个路径了。虽然我们当前这个页面和这个目录它俩相隔比较远。如果是我们用相对目录的话,这个地方可能还要写好几个点,好几个斜杠对吧,但现在因为它是一个模块,直接放在这个地方,所以不需要,我们直接这样写就可以了。 这是一个引入,引入完成以后,接下来这个地方是上下文的一个渲染对象,这个是必不可少的。然后再往下就是我们要有一个处理数据的函数dealWithListData。我们先把这个给它拷贝过来,这个我们原来就有,但不同的是我们后面这个地方,没有对长列表的一个设置,这个设置其实这个是setRecycleContext,我们把这个给它拷贝过来,然后这个方法在哪里调用?在我们拿到这个列表以后对吧,我们原来这个地方我们可以看到它是这样一种方式,它是通过allList写到data数据源对象里面然后进行渲染的对不对?我们现在就不采用这种方式了,当然allList的data我们还是需要保留,这个代码可以给它去掉,然后这个地方我们调用setRecycleContext,调用我们新写的方法。 在这个里面我们看一下干了什么事情,第一步我们需要判断ctx它是不是已经实例化了。所以这一步是实例化,在这个里面我们看到两个名称一个是recycleId,一个是recycleList。这两个名称在我们的wxml里面我们可以看到在这个里面这个地方有一个对吧,它跟这两个名字是对应的,它必须一致,不一致的话就会出现问题。然后下面会有一些关于itemSize的一个设置,itemSize这个里面用到了一个rpx2px,就是一种变量,一种单位的转换,转换我们方法是在这个地方写的。它本质上是拿这个 将rpx单位转成px这样的一个作用,然后给它转完以后将这个值给它传进来,这个值从哪来?这个值其实是我们运行的时候通过我们这个工具查看的。它本质上高是固定的,它每个单元元素的高是固定,所以直接写在这个地方就可以了,这样的一种方式。 然后这个地方其实也是,它是在哪个地方开始渲染的?最后然后去参数拼接完以后就创建这个对象,这个它只需要创建一次,第二次就不需要了。然后将我们newList,每次我们新加载的数据通过它的一个append方法,就是组件上的一个方法,然后去传递给它由组件然后负责进行渲染,这是我们的这样的一个主要的代码。 这个代码是写完了,现在我们尝试编译一下,把调试区也给它打开看看有没有什么问题。这个地方有问题,我们这个地方看到会有一个Error对吧,recycle-view correspond to this context is detached会有一个错误,我们就检查一下这个错误出现在什么地方呢?为什么会出现这样一个错误,我们引入的组件通过指令安装的组件就是recycle-view组件,它本身里边有一些代码是需要修改的,我在示例项目里面其实也做了修改,使用的并不是直接安装的模块。你在用的时候其实你可以使用我修改之后的代码,比如说我们现在这个地方,这是我们的一个目录对不对?我们可以打开这个目录将这个组件给它拷贝一下,然后到我们这个目录,一定要到node_modules下面,因为这个是源码目录,打开这个,这个给它删掉不要。然后拷贝过来,拷贝一个新的。拷贝了以后因为源码有修改,所以我们这个地方还需要再次调用这个构建npm。把这个目标源码给它构建一下。 接下来我们再次编译一下,看看它的一个运行效果。在这个地方,我们在调试区,发现有一个错误出现了,这个错误是怎么出现的呢?它其实源于在我们代码调用的时候,我们上面没有把loading等于false给它设置。因为目前我们看到这个页面上其实显示的还是骨架屏对不对?而我们骨架屏代码里面这个地方有一个Error对吧,也就是骨架屏在显示的时候它下面这些是不显示的,其中也包括我们这个长列表recycle-view它也是不显示的。在不显示的状态下,它不显示的状态下如果想去调用我们长列表组件然后去更新它的数据,这是不允许的 ,这种情况下会报这样的一个Error,解决办法也很简单,其实我们只需要在这个地方,我们把loading等于false给它设置,设置完以后,另外我们这个地方其实关于newList还需要再设置一下,需要把这个数据给它放在我们的数据源里面,稍后我们可能会用到。 但是列表渲染其实不靠它,列表渲染其实靠的还是我们调用这个方法,调用这个方法,这个调用上面这是一种调用方式,然后下面这也是一种方式。这两种方式都可以。下面这种方式是避免我们this对象丢失,我们可以先用上面这种方式去测试,代码修改完了 我们再测试一下。现在我们看到这个列表已经显示了对吧,但是列表显示有点不太正常,它把我们原来的轮播图,顶部的banner轮播图,还有导航区全部都给覆盖住了 对不对?这是怎么造成的呢? 一般情况下就是我们的这种wxml渲染没有问题,渲染没问题,而只是这个页面展示有问题。这种问题一般就是样式问题,我们要检查我们的样式是不是有些设置的不合适的地方,在我们这个里面其中有两个涉及到它一个是top-banner,另外是一个top-nav。这里面有一个position等于absolute,代表是绝对定位。我们需要将这两个给它去掉,不需要绝对定位,清一下编译缓存,然后再看一下它的表现,整体冷启动的一个表现。首先我们看到骨架屏对不对,然后看到渲染,整体上看起来,启动是不是感觉比原来的快了一点点对吧。而且我们看到system Launch Time这个地方启动的时间 冷启动的时间是2.9,大概是2922毫秒 2.9秒,比原来的7秒已经大大的有所优化了。 这就是我们关于recycle-view 长列表组件的一个使用,最后总结一下recycle-view组件有以下优点: 第一点它很好地实现虚拟DOM这样的一个优化思想; 第二点就是稍后我们还会看到结合这个滚动事件scrolltolower,它还可以实现主页加载与更新列表数据; 第三点它本身已经开启了throttle函数节流限制,稍后我们还会对这个函数节流做进一步的一个介绍。它本质上是为了减少不必要的 多余的CPU浪费 资源消耗; 第四点它预留了插槽。我们可以看到它有before以及after slot方便开发者添加个性的业务逻辑,所以对于长内容列表渲染 recycle-view组件它是一个不错的选择,没有必要再另造轮子了,对于组件中的一些些许不足我们只需要在源码上稍加修改就可以了。 现在我们在屏幕上看到的这几个网址是我们这节课用到的一些文档、一些网址。这节课我们就讲到这里。 这节课我们主要学习了recycle-view组件的使用,它是一个渲染长内容列表的利器,下节课我们学习使用页面容器。 这里有一个问题留给你思考一下:当用户在iOS设备上使用左滑手势或者是在Android设备上按一下返回键,这个返回键是物理的返回键,位于它这个屏幕的下方,用户的真实想法他可能只是关闭从底部滑出的半屏窗口而不是返回到上一个页面,这种情况下在小程序里面应该怎么优化、怎么处理呢? 下节课我们一起深入探讨一下这个问题。 点击查看开放文档: recycle-view scroll-view