目录
- 一、定义请求参数对象
- 二、获取商品列表数据
- 三、渲染商品列表结构
- 四、把商品item封装为自定义组件
- 五、使用过滤器处理价格
- 六、上拉加载更多
- 七、下拉刷新
- 八、点击商品item项跳转到详情页面
这章主要完成商品列表页面的编写:位于subpkg分包下的goods_list页面
一、定义请求参数对象
先看一下我们需要用到的后端api接口:商品列表搜索
返回结果
现在开始写前端:因为向后端发送请求,需要4个参数,所以我们可以先封装一个对象
<script>export default {data() {return {// 请求参数对象queryObj: {// 查询关键字query: '',// 商品分类idcid: '',// 页码值pagenum: 1,// 每页显示多少条数据pagesize: 10,}};},onLoad(options) {// 将页面参数转存到 this.queryobj对象中this.queryObj.query = options.query || ''this.queryObj.cid = options.cid || ''}}
</script>
二、获取商品列表数据
3.在methods中定义getGoodsList方法
methods: {// 获取商品列表方法async getGoodsList() {const {data : res} = await uni.request({url: 'https://api-hmugo-web.itheima.net/api/public/v1/goods/search',data: this.queryObj,method: 'GET',})if (res.meta.status !== 200) {return uni.showToast({title: '数据请求失败!',duration: 1500,icon: 'none',})}this.goodsList = res.message.goodsthis.total = res.message.total}}
三、渲染商品列表结构
在页面,通过v-for指令,渲染出商品的UI结构:
<template><view><view class="goods-list"><block v-for="(goods, i) in goodsList" :key='i'><view class="goods-item"><!--左侧盒子--><view class="goods-item-left"><image :src="goods.goods_small_logo" class="goods-pic"></image></view><!--右侧盒子--><view class="goods-item-right"><!--商品名字--><view class="goods-name">{{goods.goods_name}}</view><view class="goods-info-box"><view class="goods-price">${{goods.goods_price}}</view></view></view></view></block></view></view>
</template>
美化ui
<style lang="scss">.goods-item{display: flex;padding: 10px 5px;border-bottom: 1px solid #F0F0F0;.goods-item-left{margin-right: 5px;.goods-pic{width: 100px;height: 100px;display: block;}}.goods-item-right{display: flex;flex-direction: column;justify-content: space-between;.goods-name{font-size: 13px;}.goods-info-box{.goods-price{color: #C00000;font-size: 16px;}}}}</style>
查看界面(首页,分类页随便点一个进去看)
四、把商品item封装为自定义组件
创建my-goods自定义组件
将从block下开始的UI全部抽取出来(style也同理),复制到新组件my-goods统一管理,并调用my-goods自定义组件
my-goods组件:不同点,定义一个props用于接受参数
<template><view class="goods-item"><!--左侧盒子--><view class="goods-item-left"><image :src="goods.goods_small_logo" class="goods-pic"></image></view><!--右侧盒子--><view class="goods-item-right"><!--商品名字--><view class="goods-name">{{goods.goods_name}}</view><view class="goods-info-box"><view class="goods-price">${{goods.goods_price}}</view></view></view></view>
</template><script>export default {name: "my-goods",props: {goods: {type: Object,default: {}}},data() {return {};}}
</script><style lang="scss">.goods-item{display: flex;padding: 10px 5px;border-bottom: 1px solid #F0F0F0;.goods-item-left{margin-right: 5px;.goods-pic{width: 100px;height: 100px;display: block;}}.goods-item-right{display: flex;flex-direction: column;justify-content: space-between;.goods-name{font-size: 13px;}.goods-info-box{.goods-price{color: #C00000;font-size: 16px;}}}}
</style>
封装完成也能正常展示页面:
五、使用过滤器处理价格
六、上拉加载更多
1.打开项目根目录中的pages.json配置文件,为subPackages分包中的goods_list 页面配置上拉触底的距离:
2.在goods_list页面中,和methods节点平级,声明onReachBottom事件处理函数,用来监听页面的上拉触底行为
onReachBottom() {// 让页面值自增this.queryObj.pagenum++// 重新获取列表数据this.getGoodsList()}
3.改造methods中的getGoodsList函数,当请求成功之后,进行新旧数据的拼接处理
上拉页面,就可以加载后面页码的内容数据,获取之前无法展示的数据了。
这里存在一些问题需要解决: 当我们一直往下滑动请求数据时,会频繁的向我们后台发送请求获取数据,可能我们第二页还没加载完,就在发送第五页数据请求了。
所以我们需要等待第二页数据完,后续的请求都不能发起,这样才比较合理
我们可以通过开启节流阀防止发起额外的请求:
在请求数据前后打开关闭节流阀
在触发触底事件时,要判断节流阀是否开启
还有个bug:当我们页面加载完时,再上拉获取数据,还是会发送新的页面请求,但实际我们后台的pagenum已经到最后一页(只有3页数据,但在发送第四页请求),所以我们还要判断数据是否获取完毕
解决这个问题也很简单
这样就比较合理,数据加载完,不会发送新数据,再去获取列表
七、下拉刷新
enablePullDownRefresh:表示开启当前页面的下拉刷新功能
2.监听页面的onPullDownRefresh事件:(如果发生下拉事件,刷新数据)与methods平级创建
onPullDownRefresh() {// 重置关键数据this.queryObj.pagenum = 1this.total = 0this.isloading = falsethis.goodsList = []// 重新发起数据请求this.getGoodsList(() => uni.stopPullDownRefresh())}
3.修改getGoodsList函数,接受cb回调函数并按需进行调用
上拉刷新,重置我们之前发送的请求(比如之前如果向下获取过第二页,第三页数据就没了,只有第一页)
八、点击商品item项跳转到详情页面
前面做过很多了,很简单
点击成功跳转