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

refactor: uni-recycle-view调整为uni_modules

上级 0441524a
...@@ -3,16 +3,16 @@ ...@@ -3,16 +3,16 @@
<page-head :title="title"></page-head> <page-head :title="title"></page-head>
<view class="tips">list-view组件虽然在UI层有recycle机制,但长列表的vnode太多也会造成初始化卡顿。本组件仅创建部分vnode,而未使用list-view,也就是UI层其实是短列表。 <view class="tips">list-view组件虽然在UI层有recycle机制,但长列表的vnode太多也会造成初始化卡顿。本组件仅创建部分vnode,而未使用list-view,也就是UI层其实是短列表。
此示例中仅渲染滚动容器上下5屏的内容。适用于仅使用一个for循环创建所有列表项的场景。</view> 此示例中仅渲染滚动容器上下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}"> <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="item-wrapper">
<view class="name"><text style="font-size: 14px;">{{item.name}}</text></view> <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 class="info"><text style="font-size: 12px; color: #999999;">{{item.info}}</text></view>
</view> </view>
</custom-list-item> </uni-recycle-item>
</template> </template>
</custom-list-view> </uni-recycle-view>
</view> </view>
</template> </template>
...@@ -22,13 +22,7 @@ ...@@ -22,13 +22,7 @@
name : string name : string
info : string info : string
} }
import CustomListView from "./custom-list-view"
import CustomListItem from "./custom-list-item"
export default { export default {
components: {
CustomListView,
CustomListItem
},
data() { data() {
return { return {
title: '自行实现长列表组件', title: '自行实现长列表组件',
......
<template> <template>
<view ref="box" class="custom-list-item-box"> <view class="item-container">
<slot></slot> <slot></slot>
</view> </view>
</template> </template>
<script> <script>
/**
* recycle-item 长列表子项组件
* @description 用于展示超长列表数据每一项
* @property {any[]} item 当前组件渲染的列表项
*/
export default { export default {
name: "custom-list-item", name: "custom-list-item",
props: { props: {
...@@ -19,7 +24,7 @@ ...@@ -19,7 +24,7 @@
}, },
}, },
mounted() { 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!) this.setCachedSize(this.item, (ret[0] as NodeInfo).height!)
}) })
} }
...@@ -28,4 +33,4 @@ ...@@ -28,4 +33,4 @@
<style> <style>
</style> </style>
\ No newline at end of file
<template> <template>
<scroll-view class="custom-list-view-scoll-view" v-bind="$attrs" ref="scroll" @scroll="onScroll"> <scroll-view class="uni-recycle-view-main" v-bind="$attrs" ref="scroll" @scroll="onScroll">
<view class="custom-list-view-placeholder" :style="{ height: placeholderHeight + 'px' }"> <view :style="{ height: placeholderHeight + 'px' }">
<view class="custom-list-view-container" :style="{ top: containerTop + 'px' }"> <view :style="{ top: containerTop + 'px' }">
<slot :items="items"></slot> <slot :items="items"></slot>
</view> </view>
</view> </view>
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
* - list数据内每一项不可以是基础类型 * - list数据内每一项不可以是基础类型
* - item不支持设置margin,会导致计算位置不准确 * - item不支持设置margin,会导致计算位置不准确
*/ */
/**
* recycle-view 虚拟长列表组件
* @description 用于超长列表的展示
* @property {any[]} list 列表所有数据
*/
export default { export default {
name: "custom-list-view", name: "custom-list-view",
props: { props: {
...@@ -70,7 +75,7 @@ ...@@ -70,7 +75,7 @@
}, },
mounted() { mounted() {
nextTick(() => { 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.scrollElementHeight = (ret[0] as NodeInfo).height!
this.rearrange(0) this.rearrange(0)
this.initialized = true this.initialized = true
...@@ -83,7 +88,7 @@ ...@@ -83,7 +88,7 @@
return return
} }
const scrollTop = e.detail.scrollTop const scrollTop = e.detail.scrollTop
if(scrollTop === this.lastScrollTop || scrollTop < 0) { if (scrollTop === this.lastScrollTop || scrollTop < 0) {
return return
} }
this.lastScrollTop = scrollTop this.lastScrollTop = scrollTop
...@@ -117,7 +122,7 @@ ...@@ -117,7 +122,7 @@
this.offsetThreshold[2] = Math.min(scrollTop + this.scrollElementHeight * 4, this.placeholderHeight) this.offsetThreshold[2] = Math.min(scrollTop + this.scrollElementHeight * 4, this.placeholderHeight)
this.offsetThreshold[3] = Math.min(scrollTop + this.scrollElementHeight * 6, this.placeholderHeight) this.offsetThreshold[3] = Math.min(scrollTop + this.scrollElementHeight * 6, this.placeholderHeight)
const offsetStart = this.offsetThreshold[0] const offsetStart = this.offsetThreshold[0]
const offsetEnd =this.offsetThreshold[3] const offsetEnd = this.offsetThreshold[3]
const items = [] as any[] const items = [] as any[]
const defaultItemSize = this.defaultItemSize const defaultItemSize = this.defaultItemSize
const cachedSize = this.cachedSize 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 ## uni-recycle-view
::: tip 组件名:uni-recycle-view
> 代码块: `uRecycleView`、`uRecycleItem`
【TODO 链接待补充】
[点击下载&安装]()
:::
uni-recycle-view 组件是一个开源的、适用于展示超长列表的组件,它有2个优势: uni-recycle-view 组件是一个开源的、适用于展示超长列表的组件,它有2个优势:
- 更快的初始化速度 - 更快的初始化速度
- 更低的内存占用 - 更低的内存占用
### 背景 ### 背景
uni-app x 的 list-view组件,在ui层面基于原生的recycle-view封装,对于长列表的渲染资源可以复用。 uni-app x 的 list-view组件,在ui层面基于原生的recycle-view封装,对于长列表的渲染资源可以复用。
但在vue环境下,装载长列表会对列表所有数据都创建VNode,不管渲染层这些列表是否显示。创建大量VNode会影响初始化速度和内存占用。 但在vue环境下,装载长列表会对列表所有数据都创建VNode,不管渲染层这些列表是否显示。创建大量VNode会影响初始化速度和内存占用。
...@@ -29,6 +24,8 @@ uni-recycle-view 组件只创建了有限的VNode,循环复用这些VNode。un ...@@ -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 ```vue
<template> <template>
<uni-recycle-view style="flex: 1;" :list="list"> <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.
先完成此消息的编辑!
想要评论请 注册