🎈 perf(购物页面): 改善滚动列表的加载
This commit is contained in:
parent
9a759f67f1
commit
ea6c45e560
@ -61,16 +61,16 @@ export const getFilterData = (val = {}, arr: string[] = []) => {
|
|||||||
* @param {*} object
|
* @param {*} object
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export const copyObject = (object) => {
|
export const copyObject = object => {
|
||||||
if (object.constructor == Object) {
|
if (object.constructor == Object) {
|
||||||
let keys = Object.keys(object)
|
let keys = Object.keys(object)
|
||||||
let newObject = {}
|
let newObject = {}
|
||||||
keys.map((key) => {
|
keys.map(key => {
|
||||||
newObject[key] = copyObject(object[key])
|
newObject[key] = copyObject(object[key])
|
||||||
})
|
})
|
||||||
return newObject
|
return newObject
|
||||||
} else if (object.constructor == Array) {
|
} else if (object.constructor == Array) {
|
||||||
return object.map((item) => {
|
return object.map(item => {
|
||||||
return copyObject(item)
|
return copyObject(item)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -93,9 +93,17 @@ export const copyObject = (object) => {
|
|||||||
export const screenshot = (url, suffix = '!w200') => {
|
export const screenshot = (url, suffix = '!w200') => {
|
||||||
return url + suffix
|
return url + suffix
|
||||||
}
|
}
|
||||||
|
interface DataLoadingStatus {
|
||||||
|
list: any[]
|
||||||
|
total: number
|
||||||
|
status: boolean
|
||||||
|
}
|
||||||
//获取数据加载状态 //0:数据从无到有加载数据,1,没有任何数据, 2:下拉加载,3:下拉没有数据
|
//获取数据加载状态 //0:数据从无到有加载数据,1,没有任何数据, 2:下拉加载,3:下拉没有数据
|
||||||
export const dataLoadingStatus = ({ list = [], total = 0, status = false }: { list: any[]; total: number; status: true | false }) => {
|
export const dataLoadingStatus = ({ list = [], total = 0, status = true }: DataLoadingStatus) => {
|
||||||
|
// 类型校验
|
||||||
|
if (Object.prototype.toString.call(list) !== '[object Array]') {
|
||||||
|
list = []
|
||||||
|
}
|
||||||
if (list.length == 0 && status) {
|
if (list.length == 0 && status) {
|
||||||
return 0
|
return 0
|
||||||
} else if (list.length == 0 && !status) {
|
} else if (list.length == 0 && !status) {
|
||||||
@ -107,7 +115,6 @@ export const dataLoadingStatus = ({ list = [], total = 0, status = false }: { li
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function delay(delayTime = 25): Promise<null> {
|
function delay(delayTime = 25): Promise<null> {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -117,10 +124,7 @@ function delay(delayTime = 25): Promise<null> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export function delayQuerySelector(
|
export function delayQuerySelector(selectorStr: string, delayTime = 500): Promise<any[]> {
|
||||||
selectorStr: string,
|
|
||||||
delayTime = 500
|
|
||||||
): Promise<any[]> {
|
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
const selector: SelectorQuery = Taro.createSelectorQuery()
|
const selector: SelectorQuery = Taro.createSelectorQuery()
|
||||||
delay(delayTime).then(() => {
|
delay(delayTime).then(() => {
|
||||||
@ -134,7 +138,6 @@ export function delayQuerySelector(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//全局分享监听
|
//全局分享监听
|
||||||
export const shareShop = () => {
|
export const shareShop = () => {
|
||||||
const page = Taro.getCurrentInstance().page
|
const page = Taro.getCurrentInstance().page
|
||||||
@ -143,7 +146,7 @@ export const shareShop = () => {
|
|||||||
analysisShortCodeApi(page.options.share)
|
analysisShortCodeApi(page.options.share)
|
||||||
}
|
}
|
||||||
if (page && page.onShareAppMessage) {
|
if (page && page.onShareAppMessage) {
|
||||||
page.onShareAppMessage = (res) => {
|
page.onShareAppMessage = res => {
|
||||||
let path = ''
|
let path = ''
|
||||||
let title = ''
|
let title = ''
|
||||||
let imageUrl = ''
|
let imageUrl = ''
|
||||||
@ -170,5 +173,3 @@ export const shareShop = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import { ScrollView, View } from "@tarojs/components"
|
import { ScrollView, View } from '@tarojs/components'
|
||||||
import React, { memo, ReactNode, useMemo, useState } from "react"
|
import React, { memo, ReactNode, useMemo, useState } from 'react'
|
||||||
import style from "./index.module.scss"
|
import style from './index.module.scss'
|
||||||
import DotLoading from "@/components/dotLoading"
|
import DotLoading from '@/components/dotLoading'
|
||||||
import LoadingCard from "../loadingCard"
|
import LoadingCard from '../loadingCard'
|
||||||
|
|
||||||
export type StatusParam = 0|1|2|3
|
export type StatusParam = 0 | 1 | 2 | 3
|
||||||
|
|
||||||
type Params = {
|
type Params = {
|
||||||
styleObj?: React.CSSProperties
|
styleObj?: React.CSSProperties
|
||||||
@ -36,7 +36,7 @@ export default memo(
|
|||||||
selfOnRefresherRefresh,
|
selfOnRefresherRefresh,
|
||||||
selfOnRefresherRestore,
|
selfOnRefresherRestore,
|
||||||
selfOnRefresherAbort,
|
selfOnRefresherAbort,
|
||||||
safeAreaInsetBottom=true,
|
safeAreaInsetBottom = true,
|
||||||
enableLoadMoreStatus = true,
|
enableLoadMoreStatus = true,
|
||||||
children,
|
children,
|
||||||
lowerThresholdNum = 5,
|
lowerThresholdNum = 5,
|
||||||
@ -76,28 +76,29 @@ export default memo(
|
|||||||
}
|
}
|
||||||
}, [statusMore])
|
}, [statusMore])
|
||||||
|
|
||||||
|
|
||||||
const component = () => {
|
const component = () => {
|
||||||
if(enableLoadMoreStatus){
|
if (enableLoadMoreStatus) {
|
||||||
if (!moreStatus){
|
if (!moreStatus) {
|
||||||
return (
|
return (
|
||||||
<View style={{ paddingBottom: paddingBottom + 'rpx' }} className={style.scrollViewCon}>
|
<View style={{ paddingBottom: paddingBottom + 'rpx' }} className={style.scrollViewCon}>
|
||||||
{children}
|
{children}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}else{
|
} else {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{(statusMore == 2 || statusMore == 3) && (
|
{(statusMore == 2 || statusMore == 3) && (
|
||||||
<View style={{ paddingBottom: paddingBottom + 'rpx' }} className={style.scrollViewCon}>
|
<View style={{ paddingBottom: paddingBottom + 'rpx' }} className={style.scrollViewCon}>
|
||||||
{children}
|
{children}
|
||||||
<View className={style.infinite_scroll}>
|
<View className={style.infinite_scroll}>
|
||||||
{(statusMore == 2 && (
|
{statusMore == 2 ? (
|
||||||
<View className={style.loading_more}>
|
<View className={style.loading_more}>
|
||||||
加载中
|
加载中
|
||||||
<DotLoading />
|
<DotLoading />
|
||||||
</View>
|
</View>
|
||||||
)) || <View className={style.noMore}>没有更多数据了</View>}
|
) : (
|
||||||
|
<View className={style.noMore}>没有更多数据了</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
@ -106,8 +107,7 @@ export default memo(
|
|||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
}else{
|
|
||||||
return (
|
return (
|
||||||
<View style={{ paddingBottom: paddingBottom + 'rpx' }} className={style.scrollViewCon}>
|
<View style={{ paddingBottom: paddingBottom + 'rpx' }} className={style.scrollViewCon}>
|
||||||
{children}
|
{children}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Search from '@/components/search'
|
import Search from '@/components/search'
|
||||||
import { View } from '@tarojs/components'
|
import { View } from '@tarojs/components'
|
||||||
import Taro, { useDidShow } from '@tarojs/taro'
|
import Taro, { useDidShow } from '@tarojs/taro'
|
||||||
import { FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
|
import { FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useTransition } from 'react'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import classnames from 'classnames'
|
import classnames from 'classnames'
|
||||||
import IconText from '@/components/iconText'
|
import IconText from '@/components/iconText'
|
||||||
@ -15,6 +15,7 @@ import { dataLoadingStatus, debounce, getFilterData } from '@/common/util'
|
|||||||
import { ShoppingProvider } from './components/shoppingCart/index'
|
import { ShoppingProvider } from './components/shoppingCart/index'
|
||||||
import { Goods, ShoppingDispatchType, useShoppingDispatch, useShoppingState } from './context'
|
import { Goods, ShoppingDispatchType, useShoppingDispatch, useShoppingState } from './context'
|
||||||
import { alert, goLink, isEmptyObject } from '@/common/common'
|
import { alert, goLink, isEmptyObject } from '@/common/common'
|
||||||
|
import LoadingCard from '@/components/loadingCard'
|
||||||
|
|
||||||
export const Shopping: FC = memo(() => {
|
export const Shopping: FC = memo(() => {
|
||||||
// 计算总的预估金额
|
// 计算总的预估金额
|
||||||
@ -87,7 +88,9 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
|
|||||||
|
|
||||||
//数据加载状态
|
//数据加载状态
|
||||||
const statusMore = useMemo(() => {
|
const statusMore = useMemo(() => {
|
||||||
return dataLoadingStatus({ list: shoppingCartData.list, total: shoppingCartData.total, status: state.loading })
|
const status = dataLoadingStatus({ list: shoppingCartData.list, total: shoppingCartData.total, status: state.loading })
|
||||||
|
console.log('status==>', status)
|
||||||
|
return status
|
||||||
}, [shoppingCartData, state])
|
}, [shoppingCartData, state])
|
||||||
|
|
||||||
// useLayoutEffect 执行在DOM更新之后,浏览器绘制之前 如果放在 useEffect 里面会产生多一次不必要的回流和重绘,可能会引起视图闪现
|
// useLayoutEffect 执行在DOM更新之后,浏览器绘制之前 如果放在 useEffect 里面会产生多一次不必要的回流和重绘,可能会引起视图闪现
|
||||||
@ -112,8 +115,12 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
|
|||||||
})()
|
})()
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
const [isPending, startTransition] = useTransition()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setShoppingCartData({ list: state.data, total: state.data.length })
|
startTransition(() => {
|
||||||
|
setShoppingCartData({ list: state.data, total: state.data.length })
|
||||||
|
})
|
||||||
}, [state])
|
}, [state])
|
||||||
|
|
||||||
// 结算
|
// 结算
|
||||||
@ -228,10 +235,14 @@ const ShoppingCartContainer: FC<InternalContainer> = () => {
|
|||||||
<View className={classnames('flex-item', 'flex-col', styles['shopping--context'])}>
|
<View className={classnames('flex-item', 'flex-col', styles['shopping--context'])}>
|
||||||
<View className={classnames(styles.shopping__list__container, 'flex-item')} style={{ height: listHeightRef.current }}>
|
<View className={classnames(styles.shopping__list__container, 'flex-item')} style={{ height: listHeightRef.current }}>
|
||||||
<InfiniteScroll statusMore={statusMore} refresherEnabled={true} selfOnRefresherRefresh={handleRefresh} refresherTriggered={refreshStatus}>
|
<InfiniteScroll statusMore={statusMore} refresherEnabled={true} selfOnRefresherRefresh={handleRefresh} refresherTriggered={refreshStatus}>
|
||||||
{!!shoppingCartData?.list?.length &&
|
{isPending ? (
|
||||||
|
<LoadingCard />
|
||||||
|
) : (
|
||||||
|
!!shoppingCartData?.list?.length &&
|
||||||
shoppingCartData?.list?.map((item, index) => {
|
shoppingCartData?.list?.map((item, index) => {
|
||||||
return <ItemList itemData={item} key={index}></ItemList>
|
return <ItemList itemData={item} key={index}></ItemList>
|
||||||
})}
|
})
|
||||||
|
)}
|
||||||
</InfiniteScroll>
|
</InfiniteScroll>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
@ -110,7 +110,7 @@ export const useRequest = (
|
|||||||
success: false, // 请求是否成功
|
success: false, // 请求是否成功
|
||||||
data: {},
|
data: {},
|
||||||
msg: '',
|
msg: '',
|
||||||
loading: false,
|
loading: true,
|
||||||
error: null,
|
error: null,
|
||||||
query: {},
|
query: {},
|
||||||
filter: null,
|
filter: null,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user