为了账号安全,请及时绑定邮箱和手机立即绑定

【备战春招】第17天 商品列表加载更多及已加载完所有功能完善

标签:
小程序

课程内容:
1、创建商品为空页面显示内容Empty.vue

<template>
	<view class="empty">
		<view class="empty-container">
			<image :class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="emptyImg"></image>
		</view>
	</view>
</template>

<script>
	import emptyImg from '@/static/images/noShopper.png'
	export default {
		data () {
			return {
				emptyImg
			}
		}
	}
</script>

<style lang="scss" scoped>
	.empty {
		&-container {
			image {
				display: block;
				width: 414rpx;
				height: 336rpx;
				margin: 30rpx auto;
			}
		}
	}
</style>

2、在商品列表中导入数据为空后的引用

<template>
 <Empty v-if="noneProduct"></Empty>
</template>
<script>'
  import Empty from './Empty'
  export default {
		components: {
			Empty,
			NoMore
		 }
		
  }
</script>

3、在最外新建components目录创建公共的数据加载完成的组件NoMore.vue

<template>
	<view class="no-more">
		<view class="no-more-container">
			<text>已加载完所有数据~</text>
		</view>
	</view>
</template>

<script>
</script>

<style lang="scss" scoped>
	.no-more {
		&-container {
			padding: 60rpx 30rpx 20rpx;
			text-align: center;
			font-size: 24rpx;
		}
	}
</style>

4、在项目列表中调用使用加载更多的项目

<template>
  <view class="product-list">
    <view class="product-list-container" :class="[showMode, noneProduct ? 'none' : '']">
      <view class="list" :class="[showMode]" v-if="!noneProduct">
        <navigator
          v-for="goods in list"
          :key="goods.id"
          :url="`/pages/goods_detail/goods_detail?gid=${goods.id}`"
          hover-class="none"
          class="item">
          <image :class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="goods.image"></image>
          <view class="info">
            <view class="name">{{ goods.store_name }}</view>
            <view class="price">¥{{ goods.price }}</view>
            <view class="sales">已售{{ goods.sales }}件</view>
          </view>
        </navigator>
      </view>
	  <Empty v-if="noneProduct"></Empty>
	  <NoMore v-show="noMore"></NoMore>
    </view>
  </view>
</template>

<script>
  import NoMore from '@/components/NoMore'
  import Empty from './Empty'
  export default {
		components: {
			Empty,
			NoMore
		 },
		props: {
			list: {
				type: Array,
				default: () => []
			},
			showMode: {
				type: String,
				default: ''
			}
		},
		data () {
		  return {
		  }
		},
		computed: {
			noneProduct () {
				return this.list.length === 0
			},
			noMore () {
				return this.$parent.noMore
			}
		},
		methods: {
		}
  }
</script>

<style lang="scss" scoped>
  .product-list {
    &-container {
		min-height: calc(100vh - 86rpx - 86rpx);
		padding: 0 30rpx 42rpx;
		margin: 172rpx 0 0 0;
		box-sizing: border-box;
		&.pailie {
			background-color: #f5f5f5;
		}
		
		&.tupianpailie {
			&.none {
				background-color: #f5f5f5;
			}
		}
    }

    .list {
		&.pailie {
			display: flex;
			flex-wrap: wrap;
			justify-content: space-between;
			.item {
				width: 334rpx;
				border: 1rpx solid #eee;
				border-radius: 20rpx;
				margin-top: 20rpx;
				background-color: #fff;
				image {
				  width: 100%;
				  height: 334rpx;
				}
				.info {
					padding: 20rpx 16rpx 26rpx 16rpx;
					.name {
						overflow: hidden;
						text-overflow: ellipsis;
						white-space: nowrap;
						font-size: 30rpx;
						color: #222;
					}
					.price {
						font-size: 34rpx;
						color: #fc4141;
					}
					.sales {
						font-size: 22rpx;
						color: #aaa;
					}
				}
			}
		}
		
		&.tupianpailie {
			.item {
				display: flex;
				padding: 30rpx 0;
				border-bottom: 1rpx solid #eee;
				border-radius: 20rpx;
				margin-top: 20rpx;
				image {
				  width: 180rpx;
				  min-width: 180rpx;
				  height: 180rpx;
				}
				.info {
					padding: 20rpx 16rpx 26rpx 16rpx;
					.name {
						display: -webkit-box;
						-webkit-box-orient: vertical;
						-webkit-line-clamp: 2;
						overflow: hidden;
						font-size: 30rpx;
						color: #222;
					}
					.price {
						font-size: 34rpx;
						color: #fc4141;
					}
					.sales {
						font-size: 22rpx;
						color: #aaa;
					}
				}
			}
		}
    }
  }
</style>

5、判断数据加载完成,筛选数据为空

<template>
	<view class="goods-list">
		<view class="goods-list-container">
			<Search @search="onSearch" @switch-mode="onSwitchShowMode"></Search>
			<Sort @sort="onSort" ref="sort"></Sort>
			<ProductList :list="goodsList" :showMode="showMode"></ProductList>
		</view>
	</view>
</template>

<script>
	import { productList as productListApi } from '@/api/goods'
	import Search from './components/Search'
	import Sort from './components/Sort'
	import ProductList from './components/ProductList'
	export default {
		components: {
			Search,
			Sort,
			ProductList
		},
		data() {
			return {
				params: {
					// 一级分类id
					cid: 0,
					// 二级分类id
					sid: 0,
					// 搜索关键词
					keyword: '',
					// 价格排序
					priceOrder: '',
					// 按销量排序
					salesOrder: '',
					// 是否新品
					news: '',
					page: 1,
					limit: 20,
				},
				goodsList: [],
				showMode: '',
				noMore: false
			}
		},
		onLoad (options) {
			this.params.sid = options.sid
			this.$refs.sort.menuList[0].text = options.sname
			this.getProductList()
		},
		onReachBottom () {
			this.getProductList()
		},
		methods: {
			onSearch (keywords) {
				this.params.keyword = keywords
				this.params.page = 1
				this.noMore = false
				this.getProductList()
			},
			onSwitchShowMode (modeName) {
				this.showMode = modeName
			},
			onSort (sortParams) {
				this.params = {...this.params, ...sortParams}
				this.params.page = 1
				this.noMore = false
				this.getProductList()
			},
			async getProductList () {
				if (this.noMore) {
					return false
				}
			  const { status, data, msg } = await productListApi(this.params)
			  if (status === this.API_STATUS_CODE.SUCCESS) {
				  if (this.params.page > 1) {
					  this.goodsList = [...this.goodsList, ...data]
					  
					  if (data.length === 0) {
						  this.noMore = true
					  }
				  } else {
					  this.goodsList = data
				  }
				  
				  if (data.length) {
					  this.params.page++
				  }
			  } else {
			    uni.showToast({
			      icon: 'none',
			      title: msg,
			      duration: 3000
			    })
			  }
			}
		}
	}
</script>

<style lang="scss" scoped>
</style>

课程收获:
这节课主要学习到了在父组件中访问子组件,首先在子组件中定义ref=“任意名称”,然后通过在父组件中this.KaTeX parse error: Expected 'EOF', got '来' at position 29: …uList[0].text 来̲访问子组件的数据,子组件访问父…parent.noMore,再有学习到了uniapp中页面触底的生命周期函数onReachBottom(页面滚动到底部的事件(不是scroll-view滚到底),常用于下拉下一页数据。具体见下方注意事项),加载更多数据数据为空后通过定义一个noMore值,进行判断,然后再通过加载请求数据,加入数据为空,就设置为true,显示数据加载完成

点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
Web前端工程师
手记
粉丝
2
获赞与收藏
23

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消