提交 ec4f0c7b 编写于 作者: 雪洛's avatar 雪洛

refactor: uni-recycle-view调整为uni_modules

上级 0441524a
......@@ -3,16 +3,16 @@
<page-head :title="title"></page-head>
<view class="tips">list-view组件虽然在UI层有recycle机制,但长列表的vnode太多也会造成初始化卡顿。本组件仅创建部分vnode,而未使用list-view,也就是UI层其实是短列表。
此示例中仅渲染滚动容器上下5屏的内容。适用于仅使用一个for循环创建所有列表项的场景。</view>
<custom-list-view style="flex: 1;" :list="list" @scrolltoupper="scrolltoupper" @scroll="scroll">
<uni-recycle-view style="flex: 1;" :list="list" @scrolltoupper="scrolltoupper" @scroll="scroll">
<template v-slot:default="{items}">
<custom-list-item class="item" v-for="item in (items as Item[])" :item="item" :key="item.id">
<uni-recycle-item class="item" v-for="item in (items as Item[])" :item="item" :key="item.id">
<view class="item-wrapper">
<view class="name"><text style="font-size: 14px;">{{item.name}}</text></view>
<view class="info"><text style="font-size: 12px; color: #999999;">{{item.info}}</text></view>
</view>
</custom-list-item>
</uni-recycle-item>
</template>
</custom-list-view>
</uni-recycle-view>
</view>
</template>
......@@ -22,13 +22,7 @@
name : string
info : string
}
import CustomListView from "./custom-list-view"
import CustomListItem from "./custom-list-item"
export default {
components: {
CustomListView,
CustomListItem
},
data() {
return {
title: '自行实现长列表组件',
......
<template>
<view ref="box" class="custom-list-item-box">
<view class="item-container">
<slot></slot>
</view>
</template>
<script>
/**
* recycle-item 长列表子项组件
* @description 用于展示超长列表数据每一项
* @property {any[]} item 当前组件渲染的列表项
*/
export default {
name: "custom-list-item",
props: {
......@@ -19,7 +24,7 @@
},
},
mounted() {
uni.createSelectorQuery().in(this).select('.custom-list-item-box').boundingClientRect().exec((ret) => {
uni.createSelectorQuery().in(this).select('.item-container').boundingClientRect().exec((ret) => {
this.setCachedSize(this.item, (ret[0] as NodeInfo).height!)
})
}
......
<template>
<scroll-view class="custom-list-view-scoll-view" v-bind="$attrs" ref="scroll" @scroll="onScroll">
<view class="custom-list-view-placeholder" :style="{ height: placeholderHeight + 'px' }">
<view class="custom-list-view-container" :style="{ top: containerTop + 'px' }">
<scroll-view class="uni-recycle-view-main" v-bind="$attrs" ref="scroll" @scroll="onScroll">
<view :style="{ height: placeholderHeight + 'px' }">
<view :style="{ top: containerTop + 'px' }">
<slot :items="items"></slot>
</view>
</view>
......@@ -16,6 +16,11 @@
* - list数据内每一项不可以是基础类型
* - item不支持设置margin,会导致计算位置不准确
*/
/**
* recycle-view 虚拟长列表组件
* @description 用于超长列表的展示
* @property {any[]} list 列表所有数据
*/
export default {
name: "custom-list-view",
props: {
......@@ -70,7 +75,7 @@
},
mounted() {
nextTick(() => {
uni.createSelectorQuery().in(this).select('.custom-list-view-scoll-view').boundingClientRect().exec((ret) => {
uni.createSelectorQuery().in(this).select('.uni-recycle-view-main').boundingClientRect().exec((ret) => {
this.scrollElementHeight = (ret[0] as NodeInfo).height!
this.rearrange(0)
this.initialized = true
......@@ -83,7 +88,7 @@
return
}
const scrollTop = e.detail.scrollTop
if(scrollTop === this.lastScrollTop || scrollTop < 0) {
if (scrollTop === this.lastScrollTop || scrollTop < 0) {
return
}
this.lastScrollTop = scrollTop
......@@ -117,7 +122,7 @@
this.offsetThreshold[2] = Math.min(scrollTop + this.scrollElementHeight * 4, this.placeholderHeight)
this.offsetThreshold[3] = Math.min(scrollTop + this.scrollElementHeight * 6, this.placeholderHeight)
const offsetStart = this.offsetThreshold[0]
const offsetEnd =this.offsetThreshold[3]
const offsetEnd = this.offsetThreshold[3]
const items = [] as any[]
const defaultItemSize = this.defaultItemSize
const cachedSize = this.cachedSize
......
{
"id": "uni-recycle-view",
"displayName": "uni-recycle-view",
"version": "1.0.0",
"description": "优化了加载速度及内存占用的长列表组件",
"keywords": [
"recycle-view",
"长列表"
],
"repository": "",
"engines": {
"HBuilderX": "^4.0.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "",
"data": "",
"permissions": ""
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "u",
"aliyun": "u",
"alipay": "u"
},
"client": {
"Vue": {
"vue2": "u",
"vue3": "u"
},
"App": {
"app-vue": "u",
"app-nvue": "u",
"app-uvue": "u"
},
"H5-mobile": {
"Safari": "u",
"Android Browser": "u",
"微信浏览器(Android)": "u",
"QQ浏览器(Android)": "u"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "u",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
## uni-recycle-view
::: tip 组件名:uni-recycle-view
> 代码块: `uRecycleView`、`uRecycleItem`
【TODO 链接待补充】
[点击下载&安装]()
:::
uni-recycle-view 组件是一个开源的、适用于展示超长列表的组件,它有2个优势:
- 更快的初始化速度
- 更低的内存占用
### 背景
uni-app x 的 list-view组件,在ui层面基于原生的recycle-view封装,对于长列表的渲染资源可以复用。
但在vue环境下,装载长列表会对列表所有数据都创建VNode,不管渲染层这些列表是否显示。创建大量VNode会影响初始化速度和内存占用。
......@@ -29,6 +24,8 @@ uni-recycle-view 组件只创建了有限的VNode,循环复用这些VNode。un
### 基本用法
示例参考:[hello uni-app-x 虚拟长列表模板](https://gitcode.net/dcloud/hello-uni-app-x/-/blob/dev/pages/template/custom-long-list/custom-long-list.uvue)
```vue
<template>
<uni-recycle-view style="flex: 1;" :list="list">
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册