微信小程序实战项目(商品列表)-four - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 小程序相关 >

微信小程序实战项目(商品列表)-four

发表时间:2020-11-19

发布人:葵宇科技

浏览次数:49

Chapter four

1.商品列表效果图

2商品列表分解图

3.商品列表业务逻辑

1.加载商品列表数据

2.启用下拉页面功能

2.1.页面的json文件中开启设置enablePullDownRefresh:true

2.2.页面的js中,绑定事件onPullDownRefresh

3.启用上拉页面功能,onReachBottom页面触底事件

4.加载下一页功能

4.接口API

1.获取商品列表数据

https://api-hmugo-web.itheima.net/api/public/v1/goods/search

5.关键技术

1.小程序配置文件中启用上拉下拉功能

1.1启用下拉功能

这个启用下拉功能用来刷新,微信小程序文档提供了刷新事件为onPullDownRefresh,首先需要在商品列表对应的页面配置进行index.json添加为 "enablePullDownRefresh": true,然后触发下拉刷新事件为onPullDownRefresh(),代码如下:

这个触发刷新事件后,就会重置数据的数组、重置页码为1、重新发送请求数据、数据请求成功回来,需要手动的关闭并等待效果。

// 下拉刷新事件 
  >// 关闭下拉刷新的窗口 如果没有调用下拉刷新的窗口 直接关闭也不会报错
 wx.stopPullDownRefresh();

因为这种等待效果大概5秒,刷新时大概一秒就完事!所以需要去关闭等待效果。注意:刷新和等待效果是两回事。

在没关闭等待效果的情况如下:

1.2启用上拉功能

启用上拉功能可以用来分页,如果没有分页的话,想想如果数据量非常大时,然后一次性地返回所有数据给前台,那么页面的打开速度及图片加载就容易会下降。考虑到用户使用流量,如果用户只看第一页的内容,而不用看下面的内容,这样会浪费流量。所以采取启用上拉分页来作优化,当使用上拉分页的时候,后台不需要一次性返回数据给前台,如果用户需要下拉下面的内容,那就会加载中加数据的内容出来了。

实现思路原理:

当用户滚到底部的时候,开始加载下一页数据。首先找到触发上拉事件(onReachBottom),然后判断一下有没有下一页数据。首先我说一下分页页数的详细,首先获取到总页数 也就是说获取数据内容的条数,然后计算最后的总页数,比如:总页数=Math.ceil(总条数/每一页数据的行数),每一页数据的行数就是显示一页数据的多少行,比如这个显示一页数据为10行,那么它就是10假如为Math.ceil(23/10)=3Math.ceil就是向上取舍近整数比如2.3取为3。然后这样获取到当前的页码,判断一下当前的页码是否大于等于总页数,如果没有下一页数据,那么到这为止,并弹出提示框;如果有下一页数据,然后来加载下一页的数据,增加当前的页码+1,重新发送请求数据并加载下一页的新数据内容,注意:如果数据请求回来,必须要对data中的数据进行拼接,而不是全部替换掉的!

1.找到触发上拉事件(onReachBottom

2.判断有没有下一页数据

2.1首先获取总条数

计算: 总页数 = Math.ceil(总条数 / 每一页数据的行数)

2.2获取到当前的页码

2.3判断一下 当前的页码是否>=总页数

3.如果没有下一页数据,弹出一个提示框“没有下一页了”。

4.如果还有下一页数据 然后来加载下一页数据

4.1 增加当前的页码+1

4.2 重新发送请求数据并加载下一页的新数据内容

4.3 如果数据请求成功回来,要对data中的数据进行拼接

// 接口要的参数
    QueryParams:{
        query:"",
        cid:"",
        pagenum:1,
        pagesize:10
    },
 // 总页数
    totalPages:1,
/**
     * 生命周期函数--监听页面加载
     */
   ><view class="tabs">
    <view class="tabs_title">
        <view 
        wx:for="{{tabs}}"
        wx:key="id"
        class="title_item  {{item.isActive?'active':''}}"
        bindtap="handleItemTap"
        data-index="{{index}}"
        >
            {{item.value}}
        </view>
    </view>
    
</view>

我相信读者小程序开发的基础或Vue的基础都能看懂,什么的语法糖其实很像Vue,我说明一下这些的作用:

1.wx:for="{{tabs}}"主要是用来渲染列表,需要的是组件之外传入,也可以在js的组件中里面自定义个数组。

2.以上的循环完成之后一般需要加上wx:key="id"及data-index="{{index}}",它们主要用来唯一标识每一项,这样后面对每一项的ID进行操作,因为我们程序一般要明确知道切换每一个项的操作,而且在切换到不同项的做出对应的操作,如果没有定义这些数据,那么后面工作会bug。

3.class="{{item.isActive?'active':' '}}"主要表示已选中的某一项,当该项被选中后需要改变某颜色,比如:当active与当前项的索引isActive相等时才表示选中。

4.bindtap=“handleItemTap”表示触发点击事件,同时在js中触发并进行操作。

另外<slot>标签其实就是叫插槽,在每不同的标题栏会有不同的显示,一般在显示内容的页面,这个slot也可以控制显示与隐藏功能。

2.JS

components/Tabs/Tabs.js,这个主要是用子组件向父组件传递数据

其实原理上来说,当点击事件触发的时候,也需要触发父组件的自定义事件,这样同时传递数据给父组件。

比如:this.triggerEvent("父组件自定义事件的名称",要传递的参数)

// components/Tabs/Tabs.js
Component({
    /**
     * 组件的属性列表
     */
    {//里面存放的是要从父组件中接收的数据
    properties: {
        tabs:{
            type:Array,
            value:[]
        }
    },

    /**
     * 组件的初始数据
     */
    data: {

    },

    /**
     * 组件的方法列表
     */
    methods: {
        // 1 点击事件
          /*点击事件触发的时候
          触发父组件中的自定义事件,同时传递数据给父组件
          this.triggerEvent("父组件自定义事件的名称",要传递的参数)*/

        handleItemTap(e){
            //1 获取点击的索引,获取ID的值
            const {index}=e.currentTarget.dataset;
            //2 触发 父组件中的事件 自定义
            this.triggerEvent("tabsItemChange",{index});
        }
    }
})

3.wxss

这是最基本的样式文件,这个很简单,详细不多说了!

/* components/Tabs/Tabs.wxss */
.tabs{}
.tabs_title{
    display: flex;
    padding:15rpx 0;

}
.title_item{
    display: flex;
    justify-content: center;
    align-items: center;
    flex:1;
    padding:15rpx 0;
}
.active{
    color:var(--themeColor);
    border-bottom:5rpx solid currentColor;
}
.tabs_content{}

以上的内容,这就是子组件的Tabs。然后接下来是父组件:

接下来的是Page/goods_list/index,这是商品列表的页面。

1.WXML

Page/goods_list/index.wxml,这作为绑定标签和父组件的自定义事件,如下:

我先说说一下,我只针对slot标签的事,其他不用管,它们都是从后台数据过来的,我们根据数组的isActive用来判断点击哪个标题栏与对应的父组件向子组件传递标签和内容。

<!-- 监听自定义事件 -->
<Tabs tabs="{{tabs}}" bindtabsItemChange="handleTabsItemChange" >
    <!-- 内容 -->
    <block wx:if="{{tabs[0].isActive}}">
        <view class="first_tab">
            <navigator class="goods_item"
            wx:for="{{goodsList}}"
            wx:key="goods_id"
            url="/pages/goos_detail/index?goods_id={{item.goods_id}}"
            >
                <!-- 左侧 图片容器 -->
                   
                <!-- 右侧 商品容器 -->
                  
            </navigator>

        </view>
    </block>
    
    <block wx:elif="{{tabs[1].isActive}}">1</block>

    <block wx:elif="{{tabs[2].isActive}}">2</block>
</Tabs>

然后子组件(components/Tabs/Tabs.wxml),slot的标签并接收到数据并显示内容。

 <view class="tabs_content">
        <slot></slot>
 </view>

2.JS

在js父组件中的数据与自定义事件。

Page({
    data: {
       tabs:[
           {
               id:0,
               value:"综合",
               isActive:true
           },
           {
               id:1,
               value:"销量", 
               isActive:false
           },
           {
                id:2,
                value:"价格",
                isActive:false
           }
       ],
       goodsList:[]
    },

    //标题点击事件 从子组件传递过来
   handleTabsItemChange(e){
       // 1 获取被点击的标题索引
       const {index}=e.detail;
       // 2 修改源数组   
       let {tabs}=this.data;
       //循环数组
     //[].forEach遍历数组,它在遍历数组的时候修改了v,也会导致原数组被修改
       tabs.forEach((v,i)=>i===index?v.isActive=true:v.isActive=false);
       // 3 赋值到data中
       this.setData({
           goodsList:res.goods
       })
   }
)}

这样搞定OK!

最终如下:

下一期就是小程序商品详情-five

不断更新中.....给知识充电中。

欢迎各位大佬评论、点赞和收藏!Thanks

相关案例查看更多