当前位置:   article > 正文

商城微信小程序(二)——完成分类页面及商品列表页_微信开发者工具商品分类页面代码

微信开发者工具商品分类页面代码

分类页面预览图:

在这里插入图片描述

分类页面主要代码

index.js

// pages/category/index.js
import {
  request
} from "../../request/index.js"
Page({

  /**
   * 页面的初始数据
   */
  data: {
    //左侧菜单数据
    leftMenuList: [],
    //右侧的商品数据
    rightContent: [],
    // 被点击的左侧菜单
    currentIndex: 0,
    //右侧距离顶部距离
    scrollTop:0,

  },
  //接口返回数据
  Cates: [],

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

    /**
     * 1,先判断本地储存中有没有旧的缓存数据
     * 本地存储数据格式:
     * {time.Data.now(),data:[.....]}
     * 2,没有数据就发送请求,
     * 3,有旧数据且旧数据没有过期,直接使用本地储存中的旧数据
     */
    const Cates = wx.getStorageSync("cates");
    if (!Cates) {
      //不存在,获取数据
      this.getCates();
    } else {
      //本地有缓存
      if (Date.now() - Cates.time > 1000 * 10) {
        //超过10s就重新发送请求
        this.getCates();
      } else {
        //可以使用本地缓存数据
        this.Cates = Cates.data;
        //构造左侧菜单数据
        let leftMenuList = this.Cates.map(v => v.cat_name);
        //构造右侧商品数据
        let rightContent = this.Cates[0].children;
        this.setData({
          leftMenuList,
          rightContent,
        })
      }
    }


  },

  //获取分类数据
  getCates() {
    request({
      url: "/categories"
    }).then(res => {
      this.Cates = res.data.message;
      //把结构数据存入本地缓存
      wx.setStorageSync('cates', {
        time: Date.now(),
        data: this.Cates
      });

      //构造左侧菜单数据
      let leftMenuList = this.Cates.map(v => v.cat_name);
      //构造右侧商品数据
      let rightContent = this.Cates[0].children;
      this.setData({
        leftMenuList,
        rightContent,
      })
    })
  },

  //左侧菜单的点击事件
  handleItemTap(e) {
    /*
    1,获取被点击菜单的索引
    2,给data中的currentIndex赋值
    3,根据不同索引渲染右侧内容
    */
    const {
      index
    } = e.currentTarget.dataset;
    let rightContent = this.Cates[index].children;
    this.setData({
      currentIndex: index,
      rightContent,
      //设置右侧距离顶部距离
      scrollTop:0,
    });

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153

index.json

{
  "usingComponents": {
    "SearchInput":"../../components/SearchInput/SearchInput"
  },
  "navigationBarTitleText": "商品分类"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

index.less

vscode的easyless插件会自动生成index.wxss

/* pages/category/index.wxss */
page {
    height: 100%;
}

.cates {
    height: 100%;

    .cates_container {
        // less中使用calc注意
        height: ~'calc(100vh - 90rpx)';
        display: flex;

        .left_menu {
            flex: 2;

            .menu_item {
                height: 80rpx;
                display: flex;
                justify-content: center;
                align-items: center;
                font-size: 30rpx;
            }

            .active {
                color: var(--themeColor);
                border-left: 5rpx solid currentColor;
            }
        }

        .right_content {
            flex: 5;

            .good_group {
                .good_title {
                    height: 80rpx;
                    display: flex;
                    justify-content: center;
                    align-items: center;

                    .delimiter {
                        color: #cccccc;
                        padding: 0 10rpx;
                    }

                    .title {}
                }

                .good_list {
                    display: flex;
                    flex-wrap: wrap;

                    navigator {
                        width: 33.33%;
                        text-align: center;

                        image {
                            width: 50%;
                        }

                        .goods_name {}
                    }

                }
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

index.wxml

<view class="cates">
    <SearchInput></SearchInput>
    <view class="cates_container">
        <!-- 左侧菜单 -->
        <scroll-view scroll-y="{{true}}" class="left_menu">
            <view class="menu_item {{index===currentIndex?'active':''}}" 
            wx:for="{{leftMenuList}}" 
            wx:key="*this"
            bindtap="handleItemTap"
            data-index="{{index}}"
            >
            {{item}}
            </view>
        </scroll-view>
        <!-- 右侧菜单 -->
        <scroll-view scroll-top="{{scrollTop}}" scroll-y="{{true}}" class="right_content">
            <view class="good_group"
            wx:for="{{rightContent}}"
            wx:for-index="index1"
            wx:for-item="item1"
            >
                <view class="good_title">
                    <text class="delimiter">/</text>
                    <text class="title">{{item1.cat_name}}</text>
                    <text class="delimiter">/</text>
                </view>
                <view class="good_list">
                    <navigator class="" target="" url="/pages/goods_list/index?cid={{item2.cat_id}}" hover-class="navigator-hover" open-type="navigate"
                    wx:for="{{item1.children}}"
                    wx:for-index="index2"
                    wx:for-item="item2"
                    wx:key="cat_id"
                    >
                    <image class="" src="{{item2.cat_icon}}" mode="widthFix" lazy-load="false" binderror="" bindload="" />
                    <view class="goods_name">{{item2.cat_name}}</view>  
                        
                    </navigator>
                      

                </view>
            </view>
        </scroll-view>
    </view>
</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

分类页面难点记录

主要是布局文件index.less的编写,注意less语法。

商品列表页面预览

商品列表页功能:支持上拉加载更多,下拉刷新等
在这里插入图片描述

商品列表页主要代码:

index.js

// pages/goods_list/index.js
import {
  request
} from "../../request/index.js"
Page({

  /**
   * 页面的初始数据
   */
  data: {
    tabs: [{
        id: 0,
        value: "综合",
        isActive: true,
      },
      {
        id: 1,
        value: "销量",
        isActive: false,
      },
      {
        id: 0,
        value: "价格",
        isActive: false,
      },
    ],
    //商品列表数据
    goodsList: [],
  },

  //接口要的参数
  QueryParams: {
    query: "",
    cid: "",
    pagenum: 1,
    pagesize: 10
  },
  //总页数
  totalPages: 1,
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    this.QueryParams.cid = options.cid;
    this.getGoodsList();
  },
  //获取商品列表页数据
  getGoodsList() {
    request({
      url: "/goods/search",
      data: this.QueryParams,
    }).then(res => {
      //console.log(res);
      //数据总条数
      const total = res.data.message.total;
      //计算总页数
      this.totalPages = Math.ceil(total/this.QueryParams.pagesize);
      //console.log(this.totalPages);
      this.setData({
        goodsList:[...this.data.goodsList,... res.data.message.goods],
      });
      //手动关闭下拉刷新界面,首次进入也不会报错,无需处理
      wx.stopPullDownRefresh();
        
    })
  },

  //标题点击事件 从子组件Tabs传递过来的
  handleTabsItemChange(e) {
    //获取被点击的标题索引
    const {
      index
    } = e.detail;
    //修改源数组
    let {
      tabs
    } = this.data;
    tabs.forEach((v, i) => i === index ? v.isActive = true : v.isActive = false);
    //赋值到data中
    this.setData({
      tabs
    });
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {
    //console.log('下拉了');
    //重置数组
    this.setData({
      goodsList:[],
    });
    //重置页码
    this.QueryParams.pagenum=1;
    //重新发送请求
    this.getGoodsList();
  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {
    //console.log('页面触底了~~');
    //判断还有没有下一页数据
    if(this.QueryParams.pagenum>=this.totalPages){
      //没有下一页数据了
      wx.showToast({
        title: '没有更多数据了',
      });
        
    }else{
      this.QueryParams.pagenum++;
      this.getGoodsList();
    }

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152

index.json

{
  "usingComponents": {
    "SearchInput":"../../components/SearchInput/SearchInput",
    "Tabs":"../../components/Tabs/Tabs"
  },
  "navigationBarTitleText": "商品列表页", 
  "enablePullDownRefresh": true,
  "backgroundTextStyle": "dark"
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

index.less

/* pages/goods_list/index.wxss */
.first_tab {
    .goods_item {
        display: flex;
        border-bottom: 1px solid #cccccc;

        .goods_img_wrap {
            flex: 2;
            display: flex;
            justify-content: center;
            align-items: center;

            image {
                width: 70%;
            }
        }

        .goods_info_wrap {
            flex: 3;
            display: flex;
            flex-direction: column;
            justify-content: space-around;

            .goods_name {
                display: -webkit-box;
                overflow: hidden;
                -webkit-box-orient: vertical;
                -webkit-line-clamp: 2;
            }

            .goods_price {
                color: var(--themeColor);
                font-size: 32rpx;
            }
        }

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

index.wxml

<SearchInput></SearchInput>
<!-- 监听自定义事件 -->
<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"
      >
        <!-- 左侧的图片容器 -->
        <view class="goods_img_wrap">
          <image class="" src="{{item.goods_small_logo}}" mode="widthFix" lazy-load="false" binderror="" bindload="" />
        </view>
        <!-- 右边的商品信息 -->
        <view class="goods_info_wrap">
          <view class="goods_name">{{item.goods_name}}</view>
          <view class="goods_price">¥{{item.goods_price}}</view>
        </view>
      </navigator>
    </view>
  </block>
  <block wx:elif="{{tabs[1].isActive}}">1</block>
  <block wx:elif="{{tabs[2].isActive}}">2</block>
</Tabs>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

商品列表页引用的组件Tabs主要代码

Tabs.js

// components/Tabs/Tabs.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    //接收父组件的传值
    tabs:{
      type:Array,
      value:[],
    }
  },

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

  },

  /**
   * 组件的方法列表
   */
  methods: {
    handleItemTap(e){
      //获取点击索引
      const {index} = e.currentTarget.dataset;
      //触发父组件的事件
      this.triggerEvent("tabsItemChange",{index})
    },
  }
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

Tabs.less

.tabs{
  .tabs_title{
      display: flex;
      
      .title_item{
          display: flex;
          padding: 15rpx 0;
          justify-content: center;
          align-items: center;
          flex: 1;
      }
  }
  .tabs_content{}  
}

.active{
    color: var(--themeColor);
    border-bottom: 5rpx solid currentColor;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Tabs.wxml

<view class="tabs">
    <view class="tabs_title">
        <view class="title_item {{item.isActive?'active':''}}" wx:for="{{tabs}}" wx:key="id" bindtap="handleItemTap" data-index="{{index}}">
            {{item.value}}
        </view>
    </view>
    <view class="tabs_content">
        <slot></slot>
    </view>
</view>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

商品列表页及Tabs组件主要技术点记录

1,父组件(商品列表页)和子组件(Tabs组件)相互传递数据问题
2,上拉加载更多、下拉刷新实现的逻辑

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/247360
推荐阅读
相关标签
  

闽ICP备14008679号