主頁 > 軟體設計 > 小程式購物城專案實戰(上篇)

小程式購物城專案實戰(上篇)

2021-10-22 08:26:09 軟體設計

購物城專案實戰(上篇)

  • 提示
  • 小程式的第三方框架
  • 資料和檔案準備
  • 開始搭建
  • 首頁-搜索框
  • 首頁-輪播圖
  • 首頁-輪播圖渲染
  • 優化資料請求方式
  • 首頁-分類導航
  • 首頁-樓層
  • 分類頁面-獲取資料
  • 分類-頁面布局
  • 點擊選單切換商品內容
  • 使用快取技術
  • 商品串列
  • 商品串列頁面
  • 商品串列的靜態樣式
  • 商品串列動態渲染
  • 加載下一頁資料
  • 下拉重繪功能
  • 添加頁面加載提示效果
  • 商品詳情頁面

提示

文章中代碼可能有粘貼不完整的地方,極少數地方,完整代碼在(下篇)中貼出,

小程式的第三方框架

  • 騰訊的 wepy 類似vue框架
  • 美團的 mpvue 類似vue框架
  • 京東的 taro 類似react框架
  • 滴滴的 chameleon
  • uni-app 類似vue框架

資料和檔案準備

介面檔案地址,(地址)
小程式開發檔案,地址
阿里巴巴字體圖示庫,地址
mdn,添加鏈接描述

開始搭建

新建一個工程,并填入自己的Appid
在這里插入圖片描述
目錄下新增以下檔案夾,
在這里插入圖片描述

在這里插入圖片描述
然后搭建專案的頁面,在pages中增添頁面,在全域配置的app.json中修改代碼,然后pages中自動添加頁面,
代碼如下

{
  "pages":[
    "pages/index/index",
    "pages/category/index",
    "pages/goods_list/index",
    "pages/goods_detail/index",
    "pages/cart/index",
    "pages/collect/index",
    "pages/order/index",
    "pages/search/index",
    "pages/user/index",
    "pages/feedback/index",
    "pages/login/index",
    "pages/auth/index",
    "pages/pay/index"],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "購物城",
    "navigationBarTextStyle":"black"
  }
}

在這里插入圖片描述
在這里插入圖片描述
引入字體圖示,阿里巴巴字體圖示庫,
首先進入阿里圖示庫官網,搜索購物相關圖示,
在這里插入圖片描述
然后點擊添加入庫,
在這里插入圖片描述
然后點擊網頁右上角圖示,選擇添加進專案,沒有專案的要自己新建一個,
在這里插入圖片描述
然后點擊生成的代碼,
在這里插入圖片描述
進入到一個網頁,然后全選網頁內容,復制,
在這里插入圖片描述
在styles中新建檔案,并把代碼粘貼到該檔案內,
在這里插入圖片描述
然后引入圖示庫,
在這里插入圖片描述
測驗一下,在index檔案夾下的index.wxml輸入代碼,
在這里插入圖片描述
效果如下
在這里插入圖片描述
搭建tabbar結構,即小程式頁面最底部的結構,新建icons檔案夾,并放入以下圖片,這些圖片可自行替換,
在這里插入圖片描述

在這里插入圖片描述
然后在全域配置的app.json中書寫代碼,

{
  "pages": [
    "pages/index/index",
    "pages/category/index",
    "pages/goods_list/index",
    "pages/goods_detail/index",
    "pages/cart/index",
    "pages/collect/index",
    "pages/order/index",
    "pages/search/index",
    "pages/user/index",
    "pages/feedback/index",
    "pages/login/index",
    "pages/auth/index",
    "pages/pay/index"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "購物城",
    "navigationBarTextStyle": "black"
  },
  "tabBar": {
    "color": "#000",
    "selectedColor": "#ff2d4a",
    "backgroundColor": "#fafafa",
    "list": [{
        "pagePath": "pages/index/index",
        "text": "首頁",
        "iconPath": "./icons/home.png",
        "selectedIconPath": "./icons/home-o.png"
      },
      {
        "pagePath": "pages/category/index",
        "text": "分類",
        "iconPath": "icons/category.png",
        "selectedIconPath": "icons/category-o.png"
      },
      {
        "pagePath": "pages/cart/index",
        "text": "購物車",
        "iconPath": "icons/cart.png",
        "selectedIconPath": "icons/cart-o.png"
      },
      {
        "pagePath": "pages/user/index",
        "text": "我的",
        "iconPath": "icons/my.png",
        "selectedIconPath": "icons/my-o.png"
      }
    ]
  },
  "sitemapLocation": "sitemap.json"
}

效果如下
在這里插入圖片描述
初始化頁面的樣式,在全域組態檔app.wxss中書寫代碼,

/**app.wxss**/
/* 引入阿里圖示庫 */
@import"./styles/iconfont.wxss";

/* 在小程式中不支持通配符 “*” */
/* 注意:所以給以下標簽寫初始化樣式時,最外層還要加一個page */
page,
view,
text,
swiper,
swiper-item,
image,
navigator {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

/* 主題顏色,通過一個變數來實作 */
page {
  /* 定義主題顏色 */
  --themColor: #eb4450;
  /* 定義統一的字體大小,小程式中1px=2rpx */
  font-size: 28rpx;
}

然后在index檔案夾下的index.wxss測驗一下使用

/* 使用主題顏色 */
view{
  color: var(--themColor);
}

效果如下
在這里插入圖片描述

隨后修改頁面頂部的背景樣式,在全域組態檔app.json中的window內的代碼修改,

  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#eb4450",
    "navigationBarTitleText": "購物城",
    "navigationBarTextStyle": "white"
  },

效果如下
在這里插入圖片描述

首頁-搜索框

在組件檔案夾下,新建SearchInput檔案夾,用來保存搜索框組件,然后右鍵選擇該檔案夾,選擇新建components,建好后的效果如下
在這里插入圖片描述
接下來是引入組件,那個頁面要用就在哪個頁面的檔案夾內引入,在index檔案夾下的index.json中引入,

{
  "usingComponents": {
    "SearchInput":"../../components/SearchInput/SearchInput"
  },
  "navigationBarTitleText": "首頁"
}

然后測驗一下在index.wxml中輸入

<view class="gouwu">
<!-- 搜索框 -->
<SearchInput></SearchInput>
</view>

效果如下

在這里插入圖片描述
然后修改搜索框樣式,首先在searchinput.wxml中修改結構,

<view class="search_input">
  <navigator>搜索</navigator>
</view>

然后在searchinput.wxss中修改樣式,

.search_input {
  height: 90rpx;
  padding: 10rpx;
  background-color: var(--themColor);
}
.search_input navigator {
  height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: #fff;
  color:slategrey;
}

效果如下
在這里插入圖片描述
增加跳轉功能,點擊搜索按鈕,跳轉到搜索頁面,
在searchinput.wxml內修改代碼

<!--components/SearchInput/SearchInput.wxml-->
<view class="search_input">
<!-- 搜索框一點擊就會跳轉到搜索頁面 -->
  <navigator url="/pages/search/index">搜索</navigator>
</view>

首頁-輪播圖

在之前準備的資料介面檔案里,獲取首頁輪播圖的API,
在這里插入圖片描述
在index檔案夾下的index.js檔案修改代碼,

Page({

  /**
   * 頁面的初始資料
   */
  data: {
    // 輪播圖陣列
    swiperList:[]
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    // 開始發送異步請求,獲取輪播圖資料
    wx.request({
      url: 'https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata',
      method: 'GET',
      success: (result) => {
        //查看回傳的資料是什么
        console.log(result);
        //設定獲取回傳的資料
        this.setData({
          swiperList:result.data.message
        })
      },
      fail: (res) => {},
      complete: (res) => {},
    })
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {
    
  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {
    
  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {
    
  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {
    
  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {
    
  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {
    
  }
})

可以看到已經成功取到回傳資料,
在這里插入圖片描述

首頁-輪播圖渲染

在首頁index檔案夾下的index.wxml書寫輪播圖結構,

<view class="gouwu">
  <!-- 搜索框 -->
  <SearchInput></SearchInput>
  <!-- 輪播圖 -->
  <view class="lunbotu">
    <!-- swiper、image等標簽一開始設定過了默認的寬度和高度 -->
    <!-- 在swiper標簽上開始autoplay自動輪播屬性,并顯示輪播指示點 和銜接輪播-->
    <swiper autoplay="true" indicator-dots="true" circular="true">
      <!-- 需要給swiper-item進行回圈 -->
      <!-- 回圈的內容都是從服務器端回傳并存入swiperList中獲得的 -->
      <swiper-item wx:for="{{swiperList}}" wx:key="goods_id">
        <navigator>
          <!-- 圖片標簽增加mode屬性widthFix,圖片標簽的內容的高寬等比例變化 -->
          <image mode="widthFix" src="{{item.image_src}}"></image>
        </navigator>
      </swiper-item>
    </swiper>
  </view>
</view>

在index.wxss中書寫相關標簽的樣式,

/* 使用主題顏色 */
view{
  color: var(--themColor);
}
/* view標簽內的image樣式 */
.lunbotu image{
width: 100%;
}
/* swiper標簽的樣式,高和寬遵從原圖的尺寸 */
.lunbotu swiper{
  width: 750rpx;
  height: 340rpx;
}

最后的效果如下
在這里插入圖片描述

優化資料請求方式

優化的手段可以通過es6的技術promise解決,在request檔案夾下新建index.js,然后輸入代碼

// params是引數
export const request = (params) => {
  return new Promise((
    // resolve是請求資料成功的結果,reject是請求失敗
    resolve,
    reject
   ) => {
    wx.request({
      // ...params是解構引數
      ...params,
      success: (result) => {
        resolve(result)
      },
      fail:(err)=>{
        reject(err);
      }
    });
  })
}

隨后在index檔案夾下的index.js內修改代碼,

//引入用來發送請求的方法,優化后的
import{request} from "../../request/index.js"
Page({
  /**
   * 頁面的初始資料
   */
  data: {
    // 輪播圖陣列
    swiperList:[]
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    // 開始發送異步請求,獲取輪播圖資料,優化的手段可以通過es6的技術promise解決
    request({url:"https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"}).then(result=>{
      this.setData({
        swiperList:result.data.message
      })
    })
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {
    
  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {
    
  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {
    
  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {
    
  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {
    
  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {
    
  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {
    
  }
})

首頁-分類導航

查看相關介面檔案的資訊,
在這里插入圖片描述
在index檔案夾下,首先是構建分類導航的結構,index.wxml內代碼

<view class="gouwu">
  <!-- 搜索框 -->
  <SearchInput></SearchInput>
  <!-- 輪播圖 -->
  <view class="lunbotu">
    <!-- swiper、image等標簽一開始設定過了默認的寬度和高度 -->
    <!-- 在swiper標簽上開始autoplay自動輪播屬性,并顯示輪播指示點 和銜接輪播-->
    <swiper autoplay="true" indicator-dots="true" circular="true">
      <!-- 需要給swiper-item進行回圈 -->
      <!-- 回圈的內容都是從服務器端回傳并存入swiperList中獲得的 -->
      <swiper-item wx:for="{{swiperList}}" wx:key="goods_id">
        <navigator>
          <!-- 圖片標簽增加mode屬性widthFix,圖片標簽的內容的高寬等比例變化 -->
          <image mode="widthFix" src="{{item.image_src}}"></image>
        </navigator>
      </swiper-item>
    </swiper>
  </view>
  <!-- 分類導航 -->
  <view class="fenlei">
    <navigator wx:for="{{cateList}}" wx:key="name">
      <image mode="widthFix" src="{{item.image_src}}"></image>
    </navigator>
  </view>
</view>

然后是實作請求資料,在index.js下,

//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"
Page({
  /**
   * 頁面的初始資料
   */
  data: {
    // 輪播圖陣列
    swiperList: [],
    //導航陣列
    cateList:[]
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    // 呼叫獲取輪播圖資料方法
    this.getSwiperList(),
    // 呼叫獲取分類導航資料方法
    this.getCateList()
  },
  // 獲取輪播圖資料方法
  getSwiperList() {
    // 開始發送異步請求,獲取輪播圖資料,優化的手段可以通過es6的技術promise解決
    request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"
    }).then(result => {
      this.setData({
        swiperList: result.data.message
      })
    })
  },
  // 獲取分類導航資料
  getCateList() {
    // 開始發送異步請求,獲取輪播圖資料,優化的手段可以通過es6的技術promise解決
    request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
    }).then(result => {
      this.setData({
        cateList: result.data.message
      })
    })
  },
  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

然后是書寫樣式在index.wxss下

/* 使用主題顏色 */
view{
  color: var(--themColor);
}
/* 輪播圖的view標簽內的image樣式 */
.lunbotu image{
width: 100%;
}
/* swiper標簽的樣式,高和寬遵從原圖的尺寸 */
.lunbotu swiper{
  width: 750rpx;
  height: 340rpx;
}
/* 分類導航內的樣式 */
.fenlei{
  display: flex;
}
.fenlei navigator{
  padding: 20rpx;
  flex: 1;
}
/* 這里的圖片與它的父元素一樣寬 */
.fenlei image{
  width: 100%;
}

最終效果
在這里插入圖片描述

首頁-樓層

查看介面檔案,
在這里插入圖片描述
同理進行,發送請求,書寫樓層部分的結構,書寫樣式,
index.wxml代碼

<view class="gouwu">
  <!-- 搜索框 -->
  <SearchInput></SearchInput>
  <!-- 輪播圖 -->
  <view class="lunbotu">
    <!-- swiper、image等標簽一開始設定過了默認的寬度和高度 -->
    <!-- 在swiper標簽上開始autoplay自動輪播屬性,并顯示輪播指示點 和銜接輪播-->
    <swiper autoplay="true" indicator-dots="true" circular="true">
      <!-- 需要給swiper-item進行回圈 -->
      <!-- 回圈的內容都是從服務器端回傳并存入swiperList中獲得的 -->
      <swiper-item wx:for="{{swiperList}}" wx:key="goods_id">
        <navigator>
          <!-- 圖片標簽增加mode屬性widthFix,圖片標簽的內容的高寬等比例變化 -->
          <image mode="widthFix" src="{{item.image_src}}"></image>
        </navigator>
      </swiper-item>
    </swiper>
  </view>
  <!-- 分類導航 -->
  <view class="fenlei">
    <navigator wx:for="{{cateList}}" wx:key="name">
      <image mode="widthFix" src="{{item.image_src}}"></image>
    </navigator>
  </view>
  <!-- 樓層 -->
  <view class="louceng">
    <view class="floor_group" wx:for="{{floorList}}" wx:for-item="item1" wx:for-index="index1" wx:key="floor_title">
      <!-- 樓層的標題 -->
      <view class="title">
        <image mode="widthFix" src="{{item1.floor_title.image_src}}"></image>
      </view>
      <!-- 樓層的具體內容 -->
      <view class="list">
        <navigator wx:for="{{item1.product_list}}" wx:for-item="item2" wx:for-index="index2" wx:key="name">
          <image mode="{{index2===0? 'widthFix':'scaleToFill'}}" src="{{item2.image_src}}"></image>
        </navigator>
      </view>
    </view>
  </view>
</view>

index.wxss代碼

/* 使用主題顏色 */
view{
  color: var(--themColor);
}
/* 輪播圖的view標簽內的image樣式 */
.lunbotu image{
width: 100%;
}
/* swiper標簽的樣式,高和寬遵從原圖的尺寸 */
.lunbotu swiper{
  width: 750rpx;
  height: 340rpx;
}
/* 分類導航內的樣式 */
.fenlei{
  display: flex;
}
.fenlei navigator{
  padding: 20rpx;
  flex: 1;
}
/* 這里的圖片與它的父元素一樣寬 */
.fenlei image{
  width: 100%;
}

/*樓層的樣式*/
.louceng .title image{
width: 100%;
}
.louceng .list{
  overflow: hidden;
}
.louceng .list navigator{
  float: left;
  width: 33.33%;
}
/* 每一樓層的后四個小圖片樣式 */
.louceng .list navigator image:nth-last-child(-n+4){
  height: 25vw;
  border-right: 10rpx solid #fff;
}
/*每一樓層的第一張大圖片樣式*/
.louceng .list navigator image:nth-child(1){
  height: 25vw;
  border-left: 10rpx solid #fff;}
/*每一樓層的四個小圖片中的第二行樣式*/
.louceng .list navigator image:nth-child(2),image:nth-child(3){
  border-bottom: 10rpx solid #fff;
}
.louceng .list navigator image{
  width: 100%;
}

index.js代碼

//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"
Page({
  /**
   * 頁面的初始資料
   */
  data: {
    // 輪播圖陣列
    swiperList: [],
    //導航陣列
    cateList: [],
    //樓層陣列
    floorList: []
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    // 呼叫獲取輪播圖資料方法
    this.getSwiperList(),
      // 呼叫獲取分類導航資料方法
      this.getCateList(),
    //呼叫獲取樓層資料的方法
    this.getFloorList()
  },
  // 獲取輪播圖資料方法
  getSwiperList() {
    // 開始發送異步請求,獲取輪播圖資料,優化的手段可以通過es6的技術promise解決
    request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/home/swiperdata"
    }).then(result => {
      this.setData({
        swiperList: result.data.message
      })
    })
  },
  // 獲取分類導航資料
  getCateList() {
    // 開始發送異步請求,獲取輪播圖資料,優化的手段可以通過es6的技術promise解決
    request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/home/catitems"
    }).then(result => {
      this.setData({
        cateList: result.data.message
      })
    })
  },
  // 獲取樓層資料
  getFloorList() {
    // 開始發送異步請求,獲取輪播圖資料,優化的手段可以通過es6的技術promise解決
    request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/home/floordata"
    }).then(result => {
      this.setData({
        floorList: result.data.message
      })
    })
  },

  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

最終效果
在這里插入圖片描述

分類頁面-獲取資料

還是看介面檔案,分類頁面的url,
在這里插入圖片描述
獲取介面資料,在category檔案夾下的index.js輸入以下代碼

//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"

// pages/category/index.js
Page({

      /**
       * 頁面的初始資料
       */
      data: {
        //左側的選單資料
        leftMenuList: [],
        //右側的選單資料
        rightMenuList: [],
      },
      //介面的回傳資料
      Cates: [],

      /**
       * 生命周期函式--監聽頁面加載
       */
      onl oad: function (options) {
        this.getCates();
      },
      // 獲取分類資料
      getCates() {
        request({
            url: "https://api-hmugo-web.itheima.net/api/public/v1/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 rightMenuList = this.Cates[0].children;
            this.setData({
              leftMenuList,
              rightMenuList
            })
          })},
          /**
           * 生命周期函式--監聽頁面初次渲染完成
           */
          onReady: function () {

          },

          /**
           * 生命周期函式--監聽頁面顯示
           */
          onShow: function () {

          },

          /**
           * 生命周期函式--監聽頁面隱藏
           */
          onHide: function () {

          },

          /**
           * 生命周期函式--監聽頁面卸載
           */
          onUnload: function () {

          },

          /**
           * 頁面相關事件處理函式--監聽用戶下拉動作
           */
          onPullDownRefresh: function () {

          },

          /**
           * 頁面上拉觸底事件的處理函式
           */
          onReachBottom: function () {

          },

          /**
           * 用戶點擊右上角分享
           */
          onShareAppMessage: function () {

          }
      })

可以看到回傳的資料
在這里插入圖片描述

分類-頁面布局

首先配置分類頁面的搜索框,與首頁的配置方法一樣,
在分類檔案夾下的index.json修改代碼

{
  "usingComponents": {
    "SearchInput": "../../components/SearchInput/SearchInput"
  },
  "navigationBarTitleText": "商品分類"
}

在index.wxml書寫結構

<!--pages/category/index.wxml-->
<view class="cates">
  <navigator>
    <!-- 搜索框 -->
    <SearchInput></SearchInput>
  </navigator>
  <!-- 頁面主體 -->
  <view class="cates_container">
    <!-- 左側選單 -->
    
    <!-- 右側商品內容 -->
  </view>
</view>

效果如下
在這里插入圖片描述
實作主體內容頁面上下滾動,可以使用小程式內置的scroll-view組件標簽,并把頁面的結構和樣式進行書寫,

<!--pages/category/index.wxml-->
<view class="cates">
  <navigator>
    <!-- 搜索框 -->
    <SearchInput></SearchInput>
  </navigator>
  <!-- 頁面主體 -->
  <view class="cates_container">
    <!-- 左側選單 -->
    <scroll-view class="left_menu " scroll-y>
      <!-- *this表示在for回圈中的item本身 -->
      <view class="menu_item {{index===currentIndex? 'active':''}}" wx:for="{{leftMenuList}}" wx:key="*this">
        {{item}}
      </view>
    </scroll-view>
    <!-- 右側商品內容 -->
    <scroll-view class="right_content" scroll-y="true">
      <view class="goods_group" wx:for="{{rightMenuList}}" wx:for-index="index1" wx:for-item="item1">
        <view class="goods_title">
          <text class="FenGeFu">/</text>
          <text class="title">{{item1.cat_name}}</text>
          <text class="FenGeFu">/</text>
        </view>
        <view class="goods_list">
          <navigator wx:for="{{item1.children}}" wx:key="item1.children.cat_id" wx:for-index="index2"
            wx:for-item="item2">
            <image mode="widthFix" src="{{item2.cat_icon}}"></image>
            <view class="goods_name">{{item2.cat_name}}</view>
          </navigator>
        </view>
      </view>
    </scroll-view>
  </view>
</view>
/* pages/category/index.wxss */
page {
  height: 100%;
}

.cates {
  height: 100%;
}

.cates_container {
  /* 頁面主體內容高度為整個頁面高度(不包含底部導航欄),減去頂部搜索框部分高度 */
  height: calc(100vh - 90rpx);
  display: flex;
}
/* 左側選單樣式 */
.cates .cates_container .left_menu {
  flex: 2;
}
.cates .cates_container .menu_item{
  height: 80rpx;
  display:flex;
  justify-content: center;
  align-items: center;
  font-size: 30rpx;
}
.cates .cates_container .active{
  color: var(--themColor);
  border-left: 5rpx solid currentColor;
}
/* 右側商品內容 */
.cates .cates_container .right_content {
  flex: 5;
}
.cates .cates_container .right_content .goods_group .goods_title{
  height: 80rpx;
  display: flex;
  justify-content: center;
  align-items: center;
}
.cates .cates_container .right_content .goods_group .goods_title .FenGeFu{
  color: #ccc;
  padding: 0 10rpx;
}
.cates .cates_container .right_content .goods_group .goods_title .title{
  
}
.cates .cates_container .right_content .goods_group .goods_list{
  display: flex;
  flex-wrap: wrap;

}
.cates .cates_container .right_content .goods_group .goods_list navigator{
  width: 33.33%;
  text-align: center;
  align-items: center;
}
.cates .cates_container .right_content .goods_group .goods_list image{
  width: 100%;
}
.cates .cates_container .right_content .goods_group .goods_list .goods_name{
  text-align: center;
  align-items: center;
}
// pages/category/index.js

//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"


Page({

      /**
       * 頁面的初始資料
       */
      data: {
        //左側的選單資料
        leftMenuList: [],
        //右側的選單資料
        rightMenuList: [],
        //被點擊的左側的選單
        currentIndex:0
      },
      //介面的回傳資料
      Cates: [],

      /**
       * 生命周期函式--監聽頁面加載
       */
      onl oad: function (options) {
        this.getCates();
      },
      // 獲取分類資料
      getCates() {
        request({
            url: "https://api-hmugo-web.itheima.net/api/public/v1/categories"
          })
          .then(res => {
            this.Cates = res.data.message;
            // // 把介面的資料存入到本地存盤中
            // wx.setStorageSync("cates", {
            //   time: Date.now(),
            //   data: this.Cates
            // });
            console.log(res);
            // 構造左側的大選單資料
            let leftMenuList = this.Cates.map(v => v.cat_name);
            // 構造右側的商品資料
            let rightMenuList = this.Cates[0].children;
            this.setData({
              leftMenuList,
              rightMenuList
            })
          })},
          /**
           * 生命周期函式--監聽頁面初次渲染完成
           */
          onReady: function () {

          },

          /**
           * 生命周期函式--監聽頁面顯示
           */
          onShow: function () {

          },

          /**
           * 生命周期函式--監聽頁面隱藏
           */
          onHide: function () {

          },

          /**
           * 生命周期函式--監聽頁面卸載
           */
          onUnload: function () {

          },

          /**
           * 頁面相關事件處理函式--監聽用戶下拉動作
           */
          onPullDownRefresh: function () {

          },

          /**
           * 頁面上拉觸底事件的處理函式
           */
          onReachBottom: function () {

          },

          /**
           * 用戶點擊右上角分享
           */
          onShareAppMessage: function () {

          }
      })

效果如下
在這里插入圖片描述

點擊選單切換商品內容

在category檔案夾下的index.js做修改,

// pages/category/index.js

//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"


Page({

  /**
   * 頁面的初始資料
   */
  data: {
    //左側的選單資料
    leftMenuList: [],
    //右側的選單資料
    rightMenuList: [],
    //被點擊的左側的選單
    currentIndex: 0
  },
  //介面的回傳資料
  Cates: [],

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    this.getCates();
  },
  // 獲取分類資料
  getCates() {
    request({
        url: "https://api-hmugo-web.itheima.net/api/public/v1/categories"
      })
      .then(res => {
        this.Cates = res.data.message;
        // 構造左側的大選單資料
        let leftMenuList = this.Cates.map(v => v.cat_name);
        // 構造右側的商品資料
        let rightMenuList = this.Cates[0].children;
        this.setData({
          leftMenuList,
          rightMenuList
        })
      })
  },
  //左側選單的點擊事件
  handleItemTap(e) {
    // console.log(e);
    // 1 獲取被點擊的標題身上的索引
    const {index}=e.currentTarget.dataset
    //2 給data中的currentIndex賦值就可以了
    // 3 構造此時右側的商品資料
    let rightMenuList = this.Cates[index].children;
    this.setData({
      currentIndex:index,
      rightMenuList
    })
  },
  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

效果
在這里插入圖片描述

使用快取技術

每次請求網路上資料時,先查看是否本地有存盤且還未過期,如果有,就優先使用本地資料,

// pages/category/index.js

//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"


Page({

  /**
   * 頁面的初始資料
   */
  data: {
    //左側的選單資料
    leftMenuList: [],
    //右側的選單資料
    rightMenuList: [],
    //被點擊的左側的選單
    currentIndex: 0
  },
  //介面的回傳資料
  Cates: [],

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    // 1先判斷一下本地存盤中有沒有舊的資料,形式是{時間戳,資料}的形式
    // 2沒有舊資料直接發送新請求
    // 3有舊的資料同時舊的資料也沒有過期就使用本地存盤中的舊資料即可

    //獲取本地存盤的資料,小程式中也是有存在本地的技術,
    const Cates = wx.getStorageSync('cates');
    //判斷
    if (!Cates) {
      //不存在 發送請求獲取資料
      this.getCates();
    }else{
      // 有舊的資料 定義過期時間為10秒
      if(Date.now()-Cates.time>10000){
        this.getCates();
      }else{
        this.Cates=Cates.data;
        console.log(Cates);
        // 構造左側的大選單資料
        let leftMenuList = this.Cates.map(v => v.cat_name);
        // 構造右側的商品資料
        let rightMenuList = this.Cates[0].children;
        this.setData({
          leftMenuList,
          rightMenuList
        })
      }
    }

  },
  // 獲取分類資料
  getCates() {
    request({
        url: "https://api-hmugo-web.itheima.net/api/public/v1/categories"
      })
      .then(res => {
        this.Cates = res.data.message;
        // 把介面的資料存入到本地存盤中
        wx.setStorageSync("cates", {
          time: Date.now(),
          data: this.Cates
        });
        // console.log(res);
        // 構造左側的大選單資料
        let leftMenuList = this.Cates.map(v => v.cat_name);
        // 構造右側的商品資料
        let rightMenuList = this.Cates[0].children;
        this.setData({
          leftMenuList,
          rightMenuList
        })
      })
  },
  //左側選單的點擊事件
  handleItemTap(e) {
    // console.log(e);
    // 1 獲取被點擊的標題身上的索引
    const {
      index
    } = e.currentTarget.dataset
    //2 給data中的currentIndex賦值就可以了
    // 3 構造此時右側的商品資料
    let rightMenuList = this.Cates[index].children;
    this.setData({
      currentIndex: index,
      rightMenuList
    })
  },
  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

商品串列

實作點擊分類中的商品,跳轉到商品串列頁面,通過url傳遞引數,比如點擊分類中的電視,其資料中有個cid=5屬性,然后這個引數會傳遞到將要跳轉的頁面,

<!--pages/category/index.wxml-->
<view class="cates">
  <navigator>
    <!-- 搜索框 -->
    <SearchInput></SearchInput>
  </navigator>
  <!-- 頁面主體 -->
  <view class="cates_container">
    <!-- 左側選單 -->
    <scroll-view class="left_menu " scroll-y>
      <!-- *this表示在for回圈中的item本身 -->
      <view class="menu_item {{index===currentIndex? 'active':''}}" wx:for="{{leftMenuList}}" wx:key="*this" bindtap="handleItemTap" data-index="{{index}}">
        {{item}}
      </view>
    </scroll-view>
    <!-- 右側商品內容 -->
    <scroll-view class="right_content" scroll-top="{{scrolltop}}" scroll-y="true">
      <view class="goods_group" wx:for="{{rightMenuList}}" wx:for-index="index1" wx:for-item="item1" wx:key="cat_id">
        <view class="goods_title">
          <text class="FenGeFu">/</text>
          <text class="title">{{item1.cat_name}}</text>
          <text class="FenGeFu">/</text>
        </view>
        <view class="goods_list">
        <!-- url傳遞商品的一些引數 -->
          <navigator open-type="navigate" wx:for="{{item1.children}}" wx:key="cat_id" wx:for-index="index2"
            wx:for-item="item2" url="/pages/goods_list/index?cid={{item2.cat_id}}">
            <image mode="widthFix" src="{{item2.cat_icon}}"></image>
            <view class="goods_name">{{item2.cat_name}}</view>
          </navigator>
        </view>
      </view>
    </scroll-view>
  </view>
</view>

然后在goods_list檔案夾下的index.js,列印一下看看是否傳遞過來引數,

// pages/goods_list/index.js
Page({

  /**
   * 頁面的初始資料
   */
  data: {

  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    console.log(options);
  }})

效果如下

在這里插入圖片描述

商品串列頁面

首先是在goods_list檔案夾下的index.js引入自定義好的組件搜索框,并在index.wxml檔案中使用該組件,另外還有一個頂部導航欄,同理在components檔案夾內新建一個tabs檔案夾,用來自定義頂部導航欄組件,隨后進行參考,
首先是tabs檔案夾內代碼

// components/tabs/tabs.js
Component({
  /**
   * 組件的屬性串列
   */
  properties: {
    tabs: {
      type: Array,
      value: [],

    }
  },

  /**
   * 組件的初始資料
   */
  data: {

  },

  /**
   * 組件的方法串列
   */
  methods: {
    //點擊事件
    handleItemTap(e) {
      //獲取點擊的索引
      const {
        index
      } = e.currentTarget.dataset;
      //觸發父組件中的事件,自定義的
      this.triggerEvent("tabsItemChange", {
        index
      });
    }
  }
})
<!--components/tabs/tabs.wxml-->
<view class="tabs">
  <view class="tabs_title">
    <!-- 里邊的三目運算子是驗證某個item是否被激活 -->
    <view wx:for="{{tabs}}" wx:key="id" class="title_item {{item.isActive?'active':''}}" bindtap="handleItemTap"
      data-index="{{index}}">{{item.value}}</view>
  </view>
  <view class="tabs_content">
  <!-- slot是插槽標簽 -->
    <slot></slot>
  </view>
</view>
/* 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(--themColor);
  border-bottom: 5rpx solid currentColor;
}
.tabs_content{}

然后是goods_list內代碼

// pages/goods_list/index.js
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    tabs: [{
        id: 0,
        value: '綜合',
        isActive: true
      },
      {
        id: 1,
        value: '銷量',
        isActive: false
      },
      {
        id: 2,
        value: '價格',
        isActive: false
      }
    ]
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    console.log(options);
  },
  //標題的點擊事件,從子組件傳遞過來
  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 () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})
{
  "usingComponents": {
    "SearchInput": "../../components/SearchInput/SearchInput",
    "tabs": "../../components/tabs/tabs"
  },
  "navigationBarTitleText": "商品串列"
}
<!--pages/goods_list/index.wxml-->
<view>
  <SearchInput></SearchInput>
  <tabs tabs="{{tabs}}" bindtabsItemChange="handleTabsItemChange">
  <!-- 如果導航欄tabs中的第0個導航被選中; 就顯示0 -->
  <block wx:if="{{tabs[0].isActive}}">0</block>
  <block wx:elif="{{tabs[1].isActive}}">1</block>
  <block wx:elif="{{tabs[2].isActive}}">2</block>
  </tabs>
</view>

最終效果如下
在這里插入圖片描述

商品串列的靜態樣式

在goods_list檔案夾內進行修改

<!--pages/goods_list/index.wxml-->
<view>
  <SearchInput></SearchInput>
  <tabs tabs="{{tabs}}" bindtabsItemChange="handleTabsItemChange">
    <!-- 如果導航欄tabs中的第0個導航被選中; 就顯示0 -->
    <block wx:if="{{tabs[0].isActive}}">
      <view class="first_tab">
        <navigator class="goods_item">
          <!-- 左側圖片容器 -->
          <view class="goods_img_wrap">
            <image mode="widthFix" src="https://api-hmugo-web.itheima.net/pyg/icon_index_nav_4@2x.png"></image>
          </view>
          <!-- 右側商品資訊容器 -->
          <view class="goods_info_wrap">
            <view class="goods_name">123sssss口口聲聲老師你打咯密碼死哦我司分為哪</view>
            <view class="goods_price">19999</view>
          </view>
        </navigator>
      </view>
    </block>
    <block wx:elif="{{tabs[1].isActive}}">
      <view class="second_tab">
        <navigator></navigator>
      </view>
    </block>
    <block wx:elif="{{tabs[2].isActive}}">
      <view class="third_tab">
        <navigator></navigator>
      </view>
    </block>
  </tabs>
</view>
/* pages/goods_list/index.wxss */
.first_tab {}

.first_tab .goods_item {
  display: flex;
  border-bottom: 1px solid #ccc;
}

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

.first_tab .goods_item .goods_img_wrap image {
  width: 60%;
}

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

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

.first_tab .goods_item .goods_info_wrap .goods_price {
  color: var(--themColor);
  font-size: 32rpx;
}

靜態樣式如下
在這里插入圖片描述

商品串列動態渲染

經過查看介面檔案,獲得請求的介面url,使用了ES7的寫法,

// 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: 2,
        value: '價格',
        isActive: false
      }
    ],
    goodsList: []
  },
  //介面要的引數
  QueryParams: {
    query: "",
    cid: "",
    pagenum: 1,
    pagesize: 10
  },
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    this.QueryParams.cid = options.cid;
    this.getGoodsList()
  },

  //獲取商品串列資料 使用ES7的寫法
  async getGoodsList() {
    const res = await request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/goods/search",
      data: this.QueryParams
    });
    console.log(res)
    this.setData({
      goodsList: res.data.message.goods
    })
  },
  //標題的點擊事件,從子組件傳遞過來
  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 () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})
<!--pages/goods_list/index.wxml-->
<view>
  <SearchInput></SearchInput>
  <tabs tabs="{{tabs}}" bindtabsItemChange="handleTabsItemChange">
    <!-- 如果導航欄tabs中的第0個導航被選中; 就顯示0 -->
    <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 mode="widthFix" src="{{item.goods_small_logo?item.goods_small_logo:'http://image1.suning.cn/uimg/b2c/newcatentries/0070078570-000000000147821386_1_400x400.jpg'}}"></image>
          </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}}">
      <view class="second_tab">
        <navigator></navigator>
      </view>
    </block>
    <block wx:elif="{{tabs[2].isActive}}">
      <view class="third_tab">
        <navigator></navigator>
      </view>
    </block>
  </tabs>
</view>

效果如下
在這里插入圖片描述

加載下一頁資料

滾動瀏覽商品串列,觸底后加載下一頁資料,
用戶上滑頁面滾動條觸底開始加載下一頁資料步驟,

  • 1找到滾動條觸底事件 微信小程式官方開發檔案尋找onReachBottom
  • 2判斷還有沒有下一頁資料
  • 3假如沒有下一頁資料彈出一個提示
  • 4假如還有下一頁資料來加載下一頁資料
// 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: 2,
        value: '價格',
        isActive: false
      }
    ],
    goodsList: []
  },

  //介面要的引數
  QueryParams: {
    query: "",
    cid: "",
    pagenum: 1,
    pagesize: 10
  },
  //總頁數初始值是1
  totalPages: 1,
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    this.QueryParams.cid = options.cid;
    this.getGoodsList()
  },

  //獲取商品串列資料 使用ES7的寫法
  async getGoodsList() {
    const res = await request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/goods/search",
      data: this.QueryParams
    });
    console.log(res)
    //獲取一下商品串列的總條數
    const total = res.data.message.total;
    //計算商品串列的總頁數=總條數除以每頁10條
    this.totalPages = Math.ceil(total / this.QueryParams.pagesize);
    console.log(this.totalPages);
    this.setData({
      //拼接了陣列
      goodsList: [...this.data.goodsList,...res.data.message.goods]
    })
  },
  //標題的點擊事件,從子組件傳遞過來
  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 () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {
//判斷是否有下一頁
if(this.QueryParams.pagenum>=this.totalPages){
  //沒有下一頁,彈出提示框
  wx.showToast({
    title: '沒有下一頁資料了',
  })

}
else{
  //還有下一頁
  console.log('%c'+"有下一頁資料");
  this.QueryParams.pagenum++;
  this.getGoodsList()
}
  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

下拉重繪功能

下拉時,重繪頁面視窗,里邊的資料重新請求并顯示,
下拉重繪頁面步驟

  • 1觸發下拉重繪事件 需要在index.json頁面組態檔中開啟一個配置項,enablePullDownRefresh
  • 2 onPullDownRefresh監聽用戶下拉操作的函式
  • 3重置資料陣列
  • 4重置頁碼設定為1
  • 5重新發送請求
  • 6請求資料回傳后,關閉下拉重繪顯示

goods_list檔案夾下的index.json代碼如下

{
  "usingComponents": {
    "SearchInput": "../../components/SearchInput/SearchInput",
    "tabs": "../../components/tabs/tabs"
  },
  "navigationBarTitleText": "商品串列",
  "enablePullDownRefresh": true,
  "backgroundTextStyle": "dark"
}
// 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: 2,
        value: '價格',
        isActive: false
      }
    ],
    goodsList: []
  },

  //介面要的引數
  QueryParams: {
    query: "",
    cid: "",
    pagenum: 1,
    pagesize: 10
  },
  //總頁數初始值是1
  totalPages: 1,
  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    this.QueryParams.cid = options.cid;
    this.getGoodsList()
  },

  //獲取商品串列資料 使用ES7的寫法
  async getGoodsList() {
    const res = await request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/goods/search",
      data: this.QueryParams
    });
    // console.log(res)
    //獲取一下商品串列的總條數
    const total = res.data.message.total;
    //計算商品串列的總頁數=總條數除以每頁10條
    this.totalPages = Math.ceil(total / this.QueryParams.pagesize);
    // console.log(this.totalPages);
    this.setData({
      //拼接了陣列
      goodsList: [...this.data.goodsList, ...res.data.message.goods]
    })
    //關閉下拉重繪的視窗
    wx.stopPullDownRefresh({
      success: (res) => {},
    })
  },
  //標題的點擊事件,從子組件傳遞過來
  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 () {
    //重置陣列
    this.setData({
      goodsList: []
    })
    //重置頁碼為1
    this.QueryParams.pagenum=1;
    //重新發送請求
    this.getGoodsList();
  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {
    //判斷是否有下一頁
    if (this.QueryParams.pagenum >= this.totalPages) {
      //沒有下一頁,彈出提示框
      wx.showToast({
        title: '沒有下一頁資料了',
      })

    } else {
      //還有下一頁
      console.log('%c' + "有下一頁資料");
      this.QueryParams.pagenum++;
      this.getGoodsList()
    }
  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

添加頁面加載提示效果

在發送資料請求前,出現加載中圖示,資料請求回來并顯示在頁面上之后,關閉這個加載中提示,使用的是wx.showLoading

  • 1把顯示頁面加載中這個提示封裝到request請求函式中,
  • 2當同時發送多個請求時,我們需要在request中進行優化加載關閉函式,

request檔案夾下的index.js代碼如下

  //發送ajax異步請求的初始次數
 let ajaxTimes = 0;
// params是引數
export const request = (params) => {
  //每發一次請求就自加
  ajaxTimes++;
  //顯示加載中效果
  wx.showLoading({
    title: '頁面加載中',
    mask: true
  })

  return new Promise((
    // resolve是請求資料成功的結果,reject是請求失敗
    resolve,
    reject
  ) => {
    wx.request({
      // ...params是解構引數
      ...params,
      success: (result) => {
        resolve(result)
      },
      fail: (err) => {
        reject(err);
      },
      //無論成功還是失敗都會觸發的事件
      complete: () => {
        //每發送完一次請求,就自減一,當為0時,表明請求完畢,關閉加載中提示
        ajaxTimes--;
        if (ajaxTimes === 0) {
          //關閉頁面加載中圖示
          wx.hideLoading()
        }
      }
    });
  })
}

效果如下
在這里插入圖片描述

商品詳情頁面

點擊商品串列中的某個商品后,需要跳轉到該商品的商品詳情頁面,所以要給goods_list檔案夾下index.wxml的商品串列增加url地址,同時傳遞點擊商品的id,

<!--pages/goods_list/index.wxml-->
<view>
  <SearchInput></SearchInput>
  <tabs tabs="{{tabs}}" bindtabsItemChange="handleTabsItemChange">
    <!-- 如果導航欄tabs中的第0個導航被選中; 就顯示0 -->
    <block wx:if="{{tabs[0].isActive}}">
      <view class="first_tab">
      <!-- 點擊某個商品后,跳轉到商品詳情頁面 url為要轉的地址-->
        <navigator class="goods_item" wx:for="{{goodsList}}" wx:key="goods_id" url="/pages/goods_detail/index?goods_id={{item.goods_id}}">
          <!-- 左側圖片容器 -->
          <view class="goods_img_wrap">
          <!-- 若有圖片缺失,則用鏈接的圖片代替 -->
            <image mode="widthFix" src="{{item.goods_small_logo?item.goods_small_logo:'http://image1.suning.cn/uimg/b2c/newcatentries/0070078570-000000000147821386_1_400x400.jpg'}}"></image>
          </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}}">
      <view class="second_tab">
        <navigator></navigator>
      </view>
    </block>
    <block wx:elif="{{tabs[2].isActive}}">
      <view class="third_tab">
        <navigator></navigator>
      </view>
    </block>
  </tabs>
</view>

然后找到商品詳情頁面goods_detail檔案夾,首先是該檔案夾下的index.json代碼修改

{
  "usingComponents": {},
  "navigationBarTitleText": "商品詳情"
}

然后在index.js中修改

// pages/goods_detail/index.js
//引入用來發送請求的方法,優化后的
import {
  request
} from "../../request/index.js"
Page({

  /**
   * 頁面的初始資料
   */
  data: {
    //請求回傳的資料是以物件形式
    goodsObj: {}
  },

  /**
   * 生命周期函式--監聽頁面加載
   */
  onl oad: function (options) {
    //拿到跳轉頁面時傳遞過來的商品id
    const {
      goods_id
    } = options;
    this.getGoodsDetail(goods_id);
  },
  /**
   * 獲取商品詳情資料
   */
  async getGoodsDetail(goods_id) {
    const goodsObj = await request({
      url: "https://api-hmugo-web.itheima.net/api/public/v1/goods/detail",
      data: {
        goods_id
      }
    });
    this.setData({
      goodsObj
    })
  },
  /**
   * 生命周期函式--監聽頁面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函式--監聽頁面顯示
   */
  onShow: function () {

  },

  /**
   * 生命周期函式--監聽頁面隱藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函式--監聽頁面卸載
   */
  onUnload: function () {

  },

  /**
   * 頁面相關事件處理函式--監聽用戶下拉動作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 頁面上拉觸底事件的處理函式
   */
  onReachBottom: function () {

  },

  /**
   * 用戶點擊右上角分享
   */
  onShareAppMessage: function () {

  }
})

可以看到現在已經能拿到資料了
在這里插入圖片描述

轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/330380.html

標籤:其他

上一篇:Java-程式邏輯控制

下一篇:2021雙十一京東活動腳本

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 面試突擊第一季,第二季,第三季

    第一季必考 https://www.bilibili.com/video/BV1FE411y79Y?from=search&seid=15921726601957489746 第二季分布式 https://www.bilibili.com/video/BV13f4y127ee/?spm_id_fro ......

    uj5u.com 2020-09-10 05:35:24 more
  • 第三單元作業總結

    1.前言 這應該是本學期最后一次寫作業總結了吧。總體來說,對作業的節奏也差不多掌握了,作業做起來的效率也更高了。雖然和之前的作業一樣,作業中都要用到新的知識,但是相比之前,更加懂得了如何利用工具以及資料。雖然之間卡過殼,但總體而言,這幾次作業還算完成的比較好。 2.作業程序總結 相比前兩個單元,此單 ......

    uj5u.com 2020-09-10 05:35:41 more
  • 北航OO(2020)第四單元博客作業暨課程總結博客

    北航OO(2020)第四單元博客作業暨課程總結博客 本單元作業的架構設計 在本單元中,由于UML圖具有比較清晰的樹形結構,因此我對其中需要進行查詢操作的元素進行了包裝,在樹的父節點中存盤所有孩子的參考。考慮到性能問題,我采用了快取機制,一次查詢后盡可能快取已經遍歷過的資訊,以減少遍歷次數。 本單元我 ......

    uj5u.com 2020-09-10 05:35:48 more
  • BUAA_OO_第四單元

    一、UML決議器設計 ? 先看下題目:第四單元實作一個基于JDK 8帶有效性檢查的UML(Unified Modeling Language)類圖,順序圖,狀態圖分析器 MyUmlInteraction,實際上我們要建立一個有向圖模型,UML中的物件(元素)可能與同級元素連接,也可與低級元素相連形成 ......

    uj5u.com 2020-09-10 05:35:54 more
  • 6.1邏輯運算子

    邏輯運算子 1. && 短路與 運算式1 && 運算式2 01.運算式1為true并且運算式2也為true 整體回傳為true 02.運算式1為false,將不會執行運算式2 整體回傳為false 03.只要有一個運算式為false 整體回傳為false 2. || 短路或 運算式1 || 運算式2 ......

    uj5u.com 2020-09-10 05:35:56 more
  • BUAAOO 第四單元 & 課程總結

    1. 第四單元:StarUml檔案決議 本單元采用了圖模型決議UML。 UML檔案可以抽象為圖、子圖、邊的邏輯結構。 在實作中,圖的節點包括類、介面、屬性,子圖包括狀態圖、順序圖等。 采用了三次遍歷UML元素的方法建圖,第一遍遍歷建點,第二、三次遍歷設定屬性、連邊,實作圖物件的初始化。這里借鑒了一些 ......

    uj5u.com 2020-09-10 05:36:06 more
  • 談談我對C# 多型的理解

    面向物件三要素:封裝、繼承、多型。 封裝和繼承,這兩個比較好理解,但要理解多型的話,可就稍微有點難度了。今天,我們就來講講多型的理解。 我們應該經常會看到面試題目:請談談對多型的理解。 其實呢,多型非常簡單,就一句話:呼叫同一種方法產生了不同的結果。 具體實作方式有三種。 一、多載 多載很簡單。 p ......

    uj5u.com 2020-09-10 05:36:09 more
  • Python 資料驅動工具:DDT

    背景 python 的unittest 沒有自帶資料驅動功能。 所以如果使用unittest,同時又想使用資料驅動,那么就可以使用DDT來完成。 DDT是 “Data-Driven Tests”的縮寫。 資料:http://ddt.readthedocs.io/en/latest/ 使用方法 dd. ......

    uj5u.com 2020-09-10 05:36:13 more
  • Python里面的xlrd模塊詳解

    那我就一下面積個問題對xlrd模塊進行學習一下: 1.什么是xlrd模塊? 2.為什么使用xlrd模塊? 3.怎樣使用xlrd模塊? 1.什么是xlrd模塊? ?python操作excel主要用到xlrd和xlwt這兩個庫,即xlrd是讀excel,xlwt是寫excel的庫。 今天就先來說一下xl ......

    uj5u.com 2020-09-10 05:36:28 more
  • 當我們創建HashMap時,底層到底做了什么?

    jdk1.7中的底層實作程序(底層基于陣列+鏈表) 在我們new HashMap()時,底層創建了默認長度為16的一維陣列Entry[ ] table。當我們呼叫map.put(key1,value1)方法向HashMap里添加資料的時候: 首先,呼叫key1所在類的hashCode()計算key1 ......

    uj5u.com 2020-09-10 05:36:38 more
最新发布
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:20:47 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:20:25 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:20:17 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:20:10 more
  • 【中介者設計模式詳解】C/Java/JS/Go/Python/TS不同語言實作

    * 中介者模式是一種行為型設計模式,它可以用來減少類之間的直接依賴關系,
    * 將物件之間的通信封裝到一個中介者物件中,從而使得各個物件之間的關系更加松散。
    * 在中介者模式中,物件之間不再直接相互互動,而是通過中介者來中轉訊息。 ......

    uj5u.com 2023-04-20 08:19:44 more
  • 露天煤礦現場調研和交流案例分享

    他們集團的資訊化公司及研究院在一個礦區正在做智能礦山的統一平臺的 試點,專案投資大概1億,包括了礦山的各方面的內容,顯示得我們這次交流有點多余。他們2年前開始做智能礦山的規劃,有很多煤礦行業專家的加持,他們的描述是非常完美,但是去年底應該上線的平臺,現在還沒有看到影子。他們確實有很多場景需求,但是被... ......

    uj5u.com 2023-04-20 08:19:07 more
  • 《社區人員管理》實戰案例設計&個人案例分享

    設計是一個讓人夢想成真程序,開始編碼、測驗、除錯之前進行需求分析和架構設計,才能保證關鍵方面都做正確 ......

    uj5u.com 2023-04-20 08:18:57 more
  • 軟體架構生態化-多角色交付的探索實踐

    作為一個技術架構師,不僅僅要緊跟行業技術趨勢,還要結合研發團隊現狀及痛點,探索新的交付方案。在日常中,你是否遇到如下問題 “ 業務需求排期長研發是瓶頸;非研發角色感受不到研發技改提效的變化;引入ISV 團隊又擔心質量和安全,培訓周期長“等等,基于此我們探索了一種新的技術體系及交付方案來解決如上問題。 ......

    uj5u.com 2023-04-20 08:18:49 more
  • 05單件模式

    #經典的單件模式 public class Singleton { private static Singleton uniqueInstance; //一個靜態變數持有Singleton類的唯一實體。 // 其他有用的實體變數寫在這里 //構造器宣告為私有,只有Singleton可以實體化這個類! ......

    uj5u.com 2023-04-19 08:42:51 more
  • 【架構與設計】常見微服務分層架構的區別和落地實踐

    軟體工程的方方面面都遵循一個最基本的道理:沒有銀彈,架構分層模型更是如此,每一種都有各自優缺點,所以請根據不同的業務場景,并遵循簡單、可演進這兩個重要的架構原則選擇合適的架構分層模型即可。 ......

    uj5u.com 2023-04-19 08:42:41 more