微信小程序笔记2

1.我的页面

1.代码

// pages/my/my.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    orderItem: [
      {
        url: '/pages/order/list/list',
        title: '商品订单',
        iconfont: 'icon-dingdanshangpindingdan'
      },
      {
        url: '/pages/order/list/list',
        title: '礼品卡订单',
        iconfont: 'icon-lipinka'
      },
      {
        url: '/pages/order/list/list',
        title: '退款/售后',
        iconfont: 'icon-tuikuan'
      }
    ]
  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  }
})
{
  "usingComponents": {},
  "navigationStyle": "custom"
}
/* pages/my/my.wxss */
.container{
  background-color: whitesmoke;
  height: 100vh;
  .top-show{
    width: 100%;
    height: 360rpx;
    .top-show-img{
      width: 100%;
      height: 100%;
    }
  }
  .bottom-show{
    position: relative;
    top: -150rpx;
    border-radius: 20rpx;
    margin: 0 auto;
    width: 96%;
    background-color: white;
    .user-container{
      display: flex;
      align-items: center;
      .avatar-container{
        margin: 20rpx;
        .avatar{
          height: 120rpx;
          width: 120rpx;
        }
      }
      .no-login{
        display: flex;
        flex-direction: column;
        font-size: 24rpx;
        color: gray;
        text:first-child {
          font-size:28rpx
        }
      }
    }
  }
  .order{
    border-radius: 20rpx;
    margin: 0 auto;
    width: 96%;
    background-color: white;
    margin-top: -80rpx;
    .order_title{
      display: flex;
      // justify-content:  设置主轴上的排列方式;
      justify-content: space-between;
      padding: 40rpx;
      .more{
        font-size: 30rpx;
        color: #ccc;
      }
    }
    .order-content{
      display: flex;
      justify-content: space-evenly;
      text-align: center;
      padding-bottom: 24rpx;
      .iconfont{
        font-size: 60rpx;
      }
      text{
        font-size: 26rpx;
      }
    }
  }
  .after-scale{
    border-radius: 20rpx;
    margin: 0 auto;
    width: 96%;
    background-color: white;
    margin-top: 20rpx;
    padding-bottom: 25rpx;
    .order-title-wrap{
      padding: 20rpx 0 0 20rpx;
    }
    .after-scale-item{
      display: flex;
      margin: 30rpx 25rpx;
      text{
        font-size: 25rpx;
        color: #999;
        margin-left: 20rpx;
      }
      .iconfont{
        color: #a2b364;
      }
    }
  }
  .info-footer{
    text-align: center;
    font-size: 24rpx;
    color: #999;
    margin-top: 30rpx;
  }
}

 

<view class="container">
<!-- 顶部展示图 -->
  <view class="top-show">
    <image src="../../assets/images/banner.jpg" mode="widthFix" class="top-show-img"/>
  </view>
  <!-- 白色背景面板 -->
  <view class="bottom-show">
    <!-- 未登录面板 -->
    <view class="user-container">
    <!-- 左边头像区域 -->
     <view class="avatar-container">
       <image src="../../assets/images/avatar.png" mode="" class="avatar"/>
     </view>
     <!-- 右边头像区域 -->
     <view class="no-login">
       <view>未登录</view>
       <view>点击授权登录</view>
     </view>
    </view>
  </view>
    <!-- 已登陆面板 -->
    <!-- 订单面板 -->
    <view class="order">
    <!-- 订单面板标题部分 -->
      <view class="order_title">
        <text class="title">我的订单</text>
        <text class="more">查看更多></text>
      </view>
      <!-- 订单面板内容部分 -->
      <view class="order-content">
        <view class="order-content-item" wx:for="{{orderItem}}" wx:key="index">
        <!-- item指数组内的项 -->
         <navigator url="/pages/tist/tist">
           <view class="iconfont {{item.iconfont}}"></view>
           <text>{{item.title}}</text>           
         </navigator>
        </view>
      </view>
    </view>
    <!-- 关于售前售后服务面板 -->
    <view class="after-scale section">
      <view class="order-title-wrap">
        <text class="title">关于售前售后服务</text>
      </view>
      <view class="after-scale-item">
        <view class="iconfont icon-kefufenxiermaikefu"></view>
        <text>可与小程序客服实时聊天或电话咨询</text>
      </view>
      <view class="after-scale-item">
        <view class="iconfont icon-shijian"></view>
        <text>小程序客服工作时间为: 8:30 ~ 20:30</text>
      </view>
      <view class="after-scale-item">
        <view class="iconfont icon-dizhiguanli"></view>
        <text>鲜花制作完毕情况下暂不支持退款</text>
      </view>
      <view class="after-scale-item">
        <view class="iconfont icon-zhangben"></view>
        <text>鲜花可以提前7-15天预订重大节假日不支持定时配送</text>
      </view>
    </view>
    <!-- 底部面板 -->
    <view class="info-footer">智谷星图技术支持</view>
</view>

 2.效果图

 3.app.json引入图标

{
  "pages": [
    "pages/my/my",
    "pages/index/index",
    "pages/cart/cart",
    "pages/goods/goods",
    "pages/category/category",
    "pages/index/banner/banner",
    "pages/index/entrance/entrance",
    "components/goods-card/goods-card",
    "components/goods-list/goods-list",
    "pages/list/list",
    "pages/tist/tist",
    "pages/test/test"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "慕尚花坊",
    "navigationBarBackgroundColor": "#FF734C"
  },
  "tabBar": {
    "color": "#252933",
    "selectedColor": "#FF734C",
    "backgroundColor": "#ffffff",
    "borderStyle": "black",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "assets/tabbar/index.png",
        "selectedIconPath": "assets/tabbar/index-active.png"
      },
      {
        "pagePath": "pages/category/category",
        "text": "分类",
        "iconPath": "assets/tabbar/cate.png",
        "selectedIconPath": "assets/tabbar/cate-active.png"
      },
      {
        "pagePath": "pages/cart/cart",
        "text": "购物车",
        "iconPath": "assets/tabbar/cart.png",
        "selectedIconPath": "assets/tabbar/cart-active.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "assets/tabbar/my.png",
        "selectedIconPath": "assets/tabbar/my-active.png"
      }
    ]
  },
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents",
  "usingComponents": {
    "van-button": "@vant/weapp/button/index",
    "van-card": "@vant/weapp/card/index",
    "van-submit-bar": "@vant/weapp/submit-bar/index",
    "van-checkbox": "@vant/weapp/checkbox/index",
    "van-checkbox-group": "@vant/weapp/checkbox-group/index",
    "van-stepper": "@vant/weapp/stepper/index",
    "van-empty": "@vant/weapp/empty/index",
    "van-goods-action": "@vant/weapp/goods-action/index",
    "van-goods-action-icon": "@vant/weapp/goods-action-icon/index",
    "van-goods-action-button": "@vant/weapp/goods-action-button/index",
    "van-action-sheet": "@vant/weapp/action-sheet/index",
    "van-panel": "@vant/weapp/panel/index"
  }
}

2. 购物车页面

1.代码


Page({

  /**
   * 页面的初始数据
   */
  data:{
        carList:[1]
      },
      navigateBtn:function(){
        wx.navigateTo({
          url: '/miniprogram/components/good',
          success:function(res){
            console.log(res);
          },
          fail:function(){
    
          },
          complete:function(){
    
          }
        })
      },
    

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  }
})
{
  "component": true,
  "styleIsolation": "shared",
  "usingComponents": {}
}

 

.container {
  background-color: whitesmoke;
  height: 100vh;
}

.carList-container{
  .carList-container-cell {
    .goods-info {
      display: flex;
      background-color: white;
      border-radius: 16rpx;
      margin: 20rpx 20rpx 10rpx 20rpx;
      padding: 24rpx 16rpx;
      .left{
        display: flex;
        align-items: center;
      }
      .mid {
        width: 300rpx;
        height: 300rpx;

        image {
          width: 100%;
          height: 100%;
        }
      }

    }

    .right {
      display: flex;
      flex-direction: column;
      height: 300rpx;
      justify-content: space-between;
      padding-left: 20rpx;
      .title{
        font-size: 26rpx;
      }
      .buy{
        display: flex;
        justify-content: space-between;
        .price{
          font-size: 30rpx;
          color: #fa4126;
        }
      }

    }
  }
}
.van-empty__bottom{
  display: flex;
  height: 250rpx;
  flex-direction: column;
  justify-content: space-between;
}

 

<view class="container">
  <!-- 购物车列表区域 -->
  <view class="carList-container" wx:if="{{carList.length}}">
    <view class="carList-container-cell" wx:for="{{carList}}" wx:key="index">
      <van-swipe-cell right-width="{{ 65 }}" left-width="{{ 65 }}">

        <van-cell-group>
          <view class="goods-info">
            <view class="left">
              <van-checkbox value="{{ false }}" checked-color="#e60017" bind:change="onChange">
              </van-checkbox>
            </view>
            <view class="mid">
              <image src="../../assets/images/floor-img.jpg" mode="" />
            </view>
            <view class="right">
              <view class="title">【11支红玫瑰】买花就送女友送爱人送老婆11111111111</view>
              <view class="buy">
                <view class="price">¥99.99</view>
                <view class="buy-btn">
                  <van-stepper value="{{ 1 }}" bind:change="onChange" />
                </view>
              </view>
            </view>
          </view>
        </van-cell-group>

      </van-swipe-cell>
    </view>
  </view>
  <!-- 购物车列表为空的情况 -->
  <van-empty description="还没有商品,快去添加吧~" wx:else="">
  <navigator url="">
    <van-button type="danger" round bindtap="navigateBtn">去购物</van-button>
  </navigator>
  <navigator url="">
    <van-button type="danger" round>去登录</van-button>
  </navigator>
</van-empty>
  <!-- 提交订单栏区域 -->
  <van-submit-bar price="{{ 3050 }}" button-text="提交订单" bind:submit="onClickButton" tip="{{ true }}">
    <van-checkbox value="{{ true }}" checked-color="#e60017" bind:change="onChange">
      全选
    </van-checkbox>
  </van-submit-bar>
</view>

 2.效果图

 3.app.json引入图标

{
  "pages": [
    "pages/my/my",
    "pages/index/index",
    "pages/cart/cart",
    "pages/goods/goods",
    "pages/category/category",
    "pages/index/banner/banner",
    "pages/index/entrance/entrance",
    "components/goods-card/goods-card",
    "components/goods-list/goods-list",
    "pages/list/list",
    "pages/tist/tist",
    "pages/test/test"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "慕尚花坊",
    "navigationBarBackgroundColor": "#FF734C"
  },
  "tabBar": {
    "color": "#252933",
    "selectedColor": "#FF734C",
    "backgroundColor": "#ffffff",
    "borderStyle": "black",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首页",
        "iconPath": "assets/tabbar/index.png",
        "selectedIconPath": "assets/tabbar/index-active.png"
      },
      {
        "pagePath": "pages/category/category",
        "text": "分类",
        "iconPath": "assets/tabbar/cate.png",
        "selectedIconPath": "assets/tabbar/cate-active.png"
      },
      {
        "pagePath": "pages/cart/cart",
        "text": "购物车",
        "iconPath": "assets/tabbar/cart.png",
        "selectedIconPath": "assets/tabbar/cart-active.png"
      },
      {
        "pagePath": "pages/my/my",
        "text": "我的",
        "iconPath": "assets/tabbar/my.png",
        "selectedIconPath": "assets/tabbar/my-active.png"
      }
    ]
  },
  "sitemapLocation": "sitemap.json",
  "lazyCodeLoading": "requiredComponents",
  "usingComponents": {
    "van-button": "@vant/weapp/button/index",
    "van-card": "@vant/weapp/card/index",
    "van-submit-bar": "@vant/weapp/submit-bar/index",
    "van-checkbox": "@vant/weapp/checkbox/index",
    "van-checkbox-group": "@vant/weapp/checkbox-group/index",
    "van-stepper": "@vant/weapp/stepper/index",
    "van-empty": "@vant/weapp/empty/index",
    "van-goods-action": "@vant/weapp/goods-action/index",
    "van-goods-action-icon": "@vant/weapp/goods-action-icon/index",
    "van-goods-action-button": "@vant/weapp/goods-action-button/index",
    "van-action-sheet": "@vant/weapp/action-sheet/index",
    "van-panel": "@vant/weapp/panel/index"
  }
}

 3.商品列表页面

1.代码

// pages/list/list.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    isFinish:"true"
  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  }
})
{
  "usingComponents": {
    "goods-card":"../../components/goods-card/goods-card"
  }
}

 

/* pages/list/list.wxss */
.container{
  .goods-list{
    display: flex;
    flex-wrap: wrap;
    justify-content: space-evenly;
  }
  .finish{
    font-size: 28rpx;
    text-align: center;
    color: #f3514f;
    line-height: 80rpx;
    border-top: 1px solid black;
  }
}

 

<!--pages/list/list.wxml-->
<view class="container">
<!-- 用户列表区域 -->
  <view class="goods-list">
   <block>
     <goods-card></goods-card>
     <goods-card></goods-card>
     <goods-card></goods-card>
     <goods-card></goods-card>
   </block>
  </view>
  <!-- 文字区域 -->
  <!-- hidden属性控制文字的显示与隐藏 -->
  <!-- 当数据加载完毕,isFinish为true,!isFinish为false,则这句话不隐藏,用户能看到这句话 -->
  <view class="finish" hidden="{{!isFinish}}">数据加载完毕了~~</view>
</view>

 2.效果图

4.商品细节页面

1.代码

// pages/detail/detail.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },
  // 点击按钮事件,控制面板显示。
  handelSheet(){
    this.setData ({
      show:true
    })
  },
  onClose(){
    this.setData ({
      show:false
    })
  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  }
})
.container {
  background-color: whitesmoke;
  height: 100vh;

  .banner-img {
    height: 800rpx;

    image {
      height: 100%;
    }
  }

  // 商品基本信息
  .content {
    background-color: white;
    // margin 设置外边距
    margin: 0 20rpx;
    // padding 设置内边距
    padding: 40rpx;
    // 设置圆角弧度
    border-radius: 20rpx;
    // 相对于原本的位置发生改变是相对定位
    // 相对于父盒子位置发生改变是绝对定位
    position: relative; //相对定位
    top: -200rpx;

    .price {
      display: flex;

      .price-num {
        color: #fa4126;
        font-weight: bolder;
        font-size: 18px;
      }

      .price-origin-num {
        color: #b4babf;
        text-decoration: line-through;
        font-size: 12px;
        margin-left: 15px;
        margin-top: 4px;
      }
    }

    .title {
      // 溢出隐藏
      overflow: hidden;
      // 超过一行就算溢出
      white-space: nowrap;
      // 溢出之后的文本
      text-overflow: ellipsis;
      font-size: 16px;
      font-weight: bolder;
      margin: 20rpx 0;
    }

    .info {
      // 溢出隐藏
      overflow: hidden;
      // 超过一行就算溢出
      white-space: nowrap;
      // 溢出之后的文本
      text-overflow: ellipsis;

      font-size: 12px;
      color: #9999;
    }
  }

  // 商品的详细信息
  .detail {
    background-color: white;
    padding: 20rpx;
    margin: -160rpx 20rpx 0 20rpx;
    border-radius: 20rpx;

    image {
      width: 100%;
      height: 700rpx;
    }
  }

  .sheet-container {
    margin: 20rpx;
    padding: 20rpx;
    border-radius: 20rpx;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    .img {
      height: 400rpx;
      width: 350rpx;
      image {
        width: 100%;
        height: 100%;
      }
    }
    .buy {
      display: flex;
      justify-content: space-between;

      .price {
        display: flex;
        color: #fa4126;
      }
    }
    .baseInfo {
      display: flex;
      // 设置主轴方向
      flex-direction: column;
      // 设置主轴上的排列方式
      justify-content: space-between;
      margin-left: 20rpx;
      .title {
        font-size: 14px;
      }
    }
  }
    .textArea {
      background-color: white;
      margin: 20rpx 20rpx;

      .title {
        margin-right: 30rpx;
        margin-bottom: 20rpx;
      }

      .box {
        background-color: whitesmoke;
        width: 92%;
        margin: 0 auto;
        border-radius: 20rpx;
        padding: 20rpx;
      }
    }
    .btn{
      width: 90%;
      margin: 20rpx auto;
    }
}
<!--pages/goods/goods.wxml-->
<view class="container">
  <!-- 商品大图 -->
  <view class="banner-img">
    <image src="../../assets/images/floor.jpg" mode="" />
  </view>
  <!-- 商品的基本信息 -->
  <view class="content">
    <!-- 商品标题 -->
    <view class="title">亲爱的/情人节网红款/19枝</view>
    <!-- 详细信息 -->
    <view class=" info">情⼈节新品情⼈节新品情⼈节新品情⼈节新品</view>
    <!-- 商品价格 -->
    <view class="price">
      <view class="price-num">¥299</view>
      <view class="price-origin-num">¥399</view>
    </view>
  </view>
  <!-- 商品的详细信息 -->
  <view class="detail">
    <image src="../../assets/images/floor-img.jpg" mode="" />
    <image src="../../assets/images/floor-img.jpg" mode="" />
    <image src="../../assets/images/floor-img.jpg" mode="" />
  </view>
  <!-- 商品的底部导航栏 -->
  <van-goods-action>
    <!-- 如果navigator标签跳转到tabber栏 则需要加open-type -->
    <navigator url="/pages/index/index" open-type="'switchTab">
      <van-goods-action-icon icon="wap-home-o" text="首页" />
    </navigator>

    <van-goods-action-icon icon="chat-o" text="客服" dot />
    <van-goods-action-icon icon="cart-o" text="购物车" info="5" />
    <van-goods-action-button text="加入购物车" type="warning" bind:tap="handelSheet" />
    <!-- handelSheel为点击按钮事件 -->
    <van-goods-action-button text="立即购买" bind:tap="handelSheet" />
  </van-goods-action>
  <!-- 自定义面板 -->
  <!-- bind:close为面板关闭事件 -->
  <van-action-sheet show="{{ show }}" bind:close="onClose"  position="bottom">
    <view class="sheet-container">
      <view class="img">
        <image src="../../assets/images/floor-img.jpg" mode="" />
      </view>
      <!-- 商品基本信息区域 -->
      <view class="baseInfo">
        <!-- 商品名称 -->
        <view class="title">亲爱的/情人节网红款/19支玫瑰</view>
        <!-- 商品价值区域 -->
        <view class="buy">
          <view class="price">
            <view class="symbol">¥</view>
            <view class="num">100</view>
          </view>
          <view class="buyBtn">
            <van-stepper value="{{1}}" bind:change="onChange" />
          </view>
        </view>
      </view>
    </view>
      <!-- 商品祝福语区域 -->
      <view class="textArea">
        <view class="title">祝福语</view>
        <textarea value="" placeholder="请输入你的祝福" class="box" />
      </view>
      <view class="btn">
        <van-button type="primary" round size="large">确定</van-button>
      </view>
  </van-action-sheet>
</view>

 2.效果图

 5.订单页面

1.代码

// pages/tist/tist.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    orderList:[1,2,3]
  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  },

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

  }
})
/* pages/tist/tist.wxss */
.container {
  background-color: whitesmoke;
  height: 100vh;

  .order-list {
    .order-item {
      width: 90%;
      height: 380rpx;
      margin: 20rpx auto;
      padding: 20rpx;
      border-radius: 20rpx;
      background-color: white;
      position: relative;

      .top {
        display: flex;
        justify-content: space-between;
        margin-bottom: 10rpx;
        font-size: 28rpx;
        font-weight: normal;
        color: #333333;
      }

      .middle {
        display: flex;

        .img {
          height: 200rpx;
          width: 250rpx;

          image {
            width: 100%;
          }
        }

        .text {
          margin: 0 220rpx 0 20rpx;

          .goods-name {
            font-size: 28rpx;
            color: #333;
            line-height: 40rpx;
            font-weight: 400;
          }

          .goods-blessing {
            font-size: 24rpx;
            height: 32rpx;
            line-height: 32rpx;
            color: #999999;
            margin: 8rpx 0;
          }
        }

        .number {
          .goods-price {
            white-space: nowrap;
            color: #fa4126;
            font-size: 24rpx;
            line-height: 48rpx;
          }

          .goods-count {
            white-space: nowrap;
            order: 4;
            text-align: right;
            font-size: 24rpx;
            color: #999;
            margin: 20rpx 0 0 auto;
          }
        }
      }

      .bottom {
        position: absolute;
        right: 50rpx;
        bottom: 50rpx;
        .total-price {
          display: flex;

          .text {
            font-size: 28rpx;
            color: #333333;
            margin-right: 10px;
          }

          .price {
            font-size: 32rpx;
            color: #fa4126;
            font-weight: bold;
          }
        }
      }
    }
  }
}

 

<!--pages/tist/tist.wxml-->
<view class="container" wx:if="{{ orderList.length }}">
  <view class="order-list" wx:for="{{orderList}}" wx:key="index">
    <view class="order-item">
      <view class="top">
        <view class="order-num">订单号<text class="num">679246470200</text></view>
        <view class="order-status">已支付</view>
      </view>
      <view class="middle">
        <view class="img">
          <image src="../../assets/images/floor-img.jpg" mode="widthFix" />
        </view>
        <view class="text">
          <view class="goods-name">不变的承诺</view>
          <view class="goods-blessing">不变的承诺</view>
        </view>
        <view class="number">
          <view class="goods-price">¥100</view>
          <view class="goods-count">x 1</view>
        </view>
        <view class="bottom">
          <view class="total-price">
            <view class="text">实付</view>
            <view class="price"><text>¥</text>666</view>
          </view>
        </view>
        </view>
      </view>
    </view>
  </view>
  <!-- 购物车列表为空的情况 -->
  <van-empty description="还没有购买商品,快去购买吧~" wx:else>
  </van-empty>

2.效果图

 6.通用模块的封装

1.1消息模块封装

1.消息弹出框的基本使用
App({
 
//页面显示生命周期函数,每打开页面就会调用一次
  onShow(){
    wx.showToast({
      title: '消息提示框',
      // 提示图标:默认成功(一个对勾)
      // error:(失败) loading(加载)  none(不显示图标)
      icon:'success',
      duration:2000,
      // 是否显示透明蒙层
      mask:true
 
 }
    })
        })
2、封装模块

1.在utils文件夹中新建一个extendApI.js文件,

2.创建⼀个 toast ⽅法对 wx.showToast() ⽅法进⾏封装,

3.使用箭头函数;

// 普通函数
// function name(params){}

// 箭头函数
// name => (参数) {函数体}

// toast = ( { 默认参数 } = {实际参数}) => {函数体}

// ()里为参数
// ()等号左边为函数toast默认的参数
// ()等号右边为调用函数toast传入的参数
const toast = ({title="消息提示框",icon='success',duration=2000,mask=true} = {}) => {
  wx.showToast({
    title,
    icon,
    duration,
    mask
  })
}
// 局部暴露toast方法
export{ toast }

// 全局挂载方法
wx.toast = toast

anlgad:页面加载时生命周期的数。
onshow:页面显示生命周期函数 。每次打开页面时都会调用一次。页面显示/切入前台前触发。gnReady:页面初次渲染完成生命周期函数。页面初次渲染完成时触发。gdids:页面隐藏生命周期函数。如页面之间跳转或通过底部 Tab 切换到其他页面,小程序切入后
gnungad:页面卸载生命周期函数。页面卸载时触发,如页面跳转或者返回到之前的页面时。

首先在appj上创建一个 toast 方法对 wx·&hgwTa&&.()方法进行封装对象中包含 title、icon、dur ation、mask 参数,并给参数设置默认值

    // wx:showToast({
    //   title: "消息提示框",
    //   // success(成功)、error(失败)、loading(加载)、none(不显示图标)
    //   icon:'success',
    //   duration:2000,
    //   // 是否显示透明蒙层
    //   mask:true
    // })

duration:是否显出透明蒙层

局部导入又分为不传入参数导入和传入参数导入

不传入参数导入

   // 不计入参数的局部导入
    // toast()

不传入参数就会一直成功,不传递参数,使用默认参值。

传入参数导入

传入参数的局部导入
    // toast({title:'数据加载完毕'})

传入部分参数,覆盖默认的参数

不传入参数的全局挂载方法wx. toast()

 传入全局参数的挂载方法

    // wx.toast({icon:'none'})

3.在app.js中调用
import { modal } from '/utils/extendApi'

1.2 模块对话框封装

wx.showModal()  模态对话框也是在项⽬中频繁使⽤的⼀个⼩程序  API ,通常⽤于向⽤户询问是否执 ⾏⼀些操作,例如:询问⽤户是否真的需要退出、是否确认删除等等。

1 // exendApi.js
2  
3 // function toast () {}
4  
5 // 在调⽤modal⽅法时,可以传递参数,也可以不传递参数。
6 // 如果不传递参数,默认值就是空对象。
7 // 如果传递参数,参数需要时⼀个对象,对象中的属性需要和wx.showModal参数保持⼀致。
8 const modal = (options = {}) => {
9 // 在⽅法内部需要通过Promise返回⽤户的操作
10 // 如果⽤户点击了确认,需要通过resolve返回true
11 // 如果⽤户点击了取消,需要通过resolve返回false
12  
13 return new Promise((resolve) => {
14 // 默认的参数
15 const defaultOpt = {
16 title: '提示', // 提示的标题
17 content: '您确定执⾏该操作吗?', // 提示的内容
18 confirmColor: '#f3514f',
19 // 接⼝调⽤结束的回调函数(调⽤成功、失败都会执⾏)
20 complete({ confirm, cancel }) {
21 confirm && console.log('点击了确定')
22 cancel && console.log('点击了取消')
23 }
24 }
25  
26 // 通过object.assgin⽅法将参数进⾏合并
27 // 需要使⽤传⼊的参数覆盖默认的参数
28 // 为了不影响默认的参数,需要将合并以后的参数赋值给⼀个空对象
29 const opts = Object.assign({}, defaultOpt, options)
30  
31 wx.showModal({32 // 将合并以后的参数通过展开运算符赋值给wx.showModal对象
33 ...opts,
34 complete({ confirm, cancel }) {
35 // 如果⽤户点击了确定,通过 resolve 抛出 true
36 // 如果⽤户点击了取消,通过 resolve 抛出 false
37 confirm && resolve(true)
38 cancel && resolve(false)
39 }
40 })
41 })
42 }
43  
44 export { modal }
45  
46 wx.modal = modal
47  
1 // app.js
2  
3 // app.js
4 // import { toast } from './utils/extendApi'
5 import './utils/extendApi'
6  
7 App({
8 // ⻚⾯显示⽣命周期函数
9 async onShow() {
10  
11 // wx.showModal({
12 // title: '提示', // 提示的标题
13 // content: '您确定执⾏该操作吗?', // 提示的内容
14 // confirmColor: '#f3514f',
15 // // 接⼝调⽤结束的回调函数(调⽤成功、失败都会执⾏)
16 // complete({ confirm, cancel }) {
17 // confirm && console.log('点击了确定')
18 // cancel && console.log('点击了取消')
19 // }
20 // })在⼩程序中,经常需要将⼀些数据存储到本地,⽅便多个⻚⾯的读取使⽤,例如:将⽤户的登录状
态、⽤户的个⼈信息存储到本地。
⼩程序提供了同步、异步两类 API 来实现本地存储操作。例如: wx.setStorageSync 、 wx.setStorage
等⽅法。
21  
22 // 不传⼊参数
23 // const res = await wx.modal()
24  
25 // 传⼊参数
26 const res = await wx.modal({
27 title:'新的提示',
28 showCancel:false
29 })
30  
31 console.log(res);
32 
33 }
34  
35 })
// 再调用modal方法是,可以传递参数,也可以不传递参数
// 如果不传递参数,默认值就是空对象
// 如果传递参数,参数需要是一个对象,对象中的属性需要和wxwx.showModal参数保持一致
const modal = (options = {}) => {
  // 通过new关键字构建一个promise对象
  // 在方法内部通过promise返回用户的操作
  // resolve为用户点击确认框的结果
  return new Promise((resolve) => {
    // 用户使用model函数时,使用showModal的默认参数
    const defaultOpt = {
      title:'提示',
      content:'你确定要执行该操作吗',
      confirmColor:'#f2514f',
      // 接口调用结束后的回调函数
      complete({confirm,cancel}){
        confirm && console.log('点击了确定');
        cancel && console.log('点击了取消');
      }
    }
    // Object.assign()方法用于将对象复制到目标对象
    // 通过Object.assign()方法将参数合并
    // 如果用户传递进来了options,就会覆盖默认参数
    // 第一个空对象参数会被赋值合并后的参数
    const opts = Object.assign({},defaultOpt,options)

    wx.showModal({
      // ...扩展运算符
      // 将合并后的参数通过展开运算符赋值给wx.showModal对象。
      ...opts,
      complete({confirm,cancel}){
        // 如果用户点击了确认,通过resolve抛出true
        confirm && console.log('点击了确定');
        // 如果用户点击了取消,通过resolve抛出false
        cancel && console.log("点击了取消");
      }
    })
  })
}
// 局部暴露modal方法
export{ modal }

在调用modal方法时,可以传递参数,也可以不传递参数
如果不传递参数,默认值就是空对象如果传递参数,参数需要是一个对象,对象中的属性需要和wx,showModal参数保持一致通过new关键字构建-个promise对象在方法内部通关promise返回用户的操作
resolve为用户点击确认框的结果
日户使用modal函数时,使用showModal的默认参数
Dbiect.assiqn0方法用于将对象复制到目标对象。
通过Obiect.assiqn0方法将参数合并
如果用户传递进来了options,就会覆盖默认参数
局部暴露:先在extendApi.js中暴露modal,然后在appjs中使用import引入modal,最后在onShow()中写入modal0)完成局部暴露

全局暴露:先在extendApijs中完成全局挂载,然后在app,js中的onShow0)中写入wx.modal0)完成全局暴露

1.3封装本地存储 API

在 utils ⽬录下新建 storage.js ⽂件 在该⽂件中,封装对本地数据进⾏ 存储、获取、删除、清除的⽅法

// wx.setStorage(option)是微信小程序存储数据的api
// setStorage()是自定义函数

// key 本地存储中的变量名
// value 变量名对应的变量值

// 以同步方法存储数据
export const setStorage = (key,value) => {
  try {
    wx.setStorageSync(key,value)
  }catch (error){
    console.log("存储失败");
  }
}
// 以同步方法获取数据
export const getStorage = (key) => {
  try{
    const value = wx.getStorageSync(key)
    if(value){
      return value
    }
  }catch (error){
    console.log("存储失败");
  }
}
// 删除数据
export const removeStorage = (key) => {
  try {
    wx.removeStorageSync(key)
  }catch(e){
    console.log("删除失败");
  }
}
// 删除全部数据
export const clearStorage = () => {
  try{
    wx.clearStorageSync()
  }catch(e){
    console.log("清除失败");
  }
}

7.网络请求封装

1.1请求封装-request⽅法

1.request⽅法封装

 

// 1.使用了微信自带的请求api wx.request
// 2.将wx.request封装到了一个名为request的函数中
// 3.将函数封装到了一个名为wxRequest的类中

// 创建一个WxRequest类
// 通过类的方式进行封装,会让代码更具有复用性
// 也可以方便添加新的属性和方法

class WxRequest{
// 用于创建和初始化类的属性和方法
constructor(){}
// request实例方法接受一个对象类型的参数
request(options){
return new Promise((resolve,reject) => {
wx.request({
        // 使用拓展运算符将request函数传来的对象参数展开
        ...options,
        // 当接口调用成功就会触发success回调函数
        success:(res) => {
resolve(res)
},
//当接口调用失败时会触发fail回调函数
fail:(err)=>{
reject(err)
}
})
})
}
}
//对wxRequest进行实例化
const instance = new WxRequest()
//将WxRequest实例暴露出去,方便在其他文件中进行使用
export default instance
// 导入在request页面中封装并暴露的instance实例
import instance from '../../utils/http'
// pages/test/test.js
Page({
// 具体阐述按钮点击事件要做什么事情
async handler(){
  //  第一种调用方法:通过.then和.catch接受返回的值
//    instance
//    .request({
//     //  请求地址
//     url:'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
//     // 请求方式
//     method:"GET"
//    })
//    .then((res) => {
//      console.log(res);
//    })
//    .catch((err) => {
//      console.log(err);
//    })

// 第二种调用方法:通过await和async接受返回的值
  // const res = await instance.request({
  //   url:'/index/findBanner',
  //   method:"GET"
  // })

  // 第三种调用方式:通过调用快捷方式接受返回的值
  // const res = await instance.get('/index/findBanner')

  // 调用并传参
  // const res = await instance.get('/index/findBanner',{test:111},
  // {timeout:20000})

  //当前请求地址是获取购物车数据,需要token才行
  const res = await instance.get('/cart/getCartList')

  console.log(res);
 },
})

 

/* pages/test/test.wxss */
.box{
  display: flex;
  // 主轴方向上居中
  justify-content: center;
  //  副轴方向上居中
  align-items: center;
  // 将盒子高度设置为页面高度
  height: 100vh;
}
<!--pages/test/test.wxml-->
<!-- <text>pages/test/test.wxml</text> -->
<view class="box">
<!-- 设置一个按钮 并给按钮设置一个名为handler的点击事件 点击按钮则会发送请求 -->
  <button type="warn" size="mini" plain bindtap="handler">测试发送请求</button>
</view>

 1.2请求封装-设置请求参数

1.创建一个WxRequest类,通过类的方式进行封装 会让代码更具有复用性,也可以方便添加新的属性和方法。
2.通过WxRequest来设定默认参数对象,请求基地址,服务器接口地址,请求方式、参数和请求头,设置数据的交互格式并且设置默认超时时间。
3.定义拦截对象包括请求拦截和响应拦截方法,方便在请求或响应之前进行处理。请求拦截器:request,响应拦截器:response
4.创建params为用户传入的请求配置项,使用Object.assign方法合并默认参数以及传递的请求参数,需要传入的参数,会覆盖默认的参数,因此传入的参数放在最后。
5.request需要接受一个对象类型的参数, 拼接完整的请求路径options.url,合并请求参数options  ={...this.defaults,...options},在发送请求之前调用请求拦截器options = this.interceptors.request(options)
6.   使用拓展运算符将request函数传来的对象参数展开 ...options, 当接口调用成功就会触发success回调函数。
不管接口成功还是失败,都需要调用响应拦截器;响应拦截器需要接受服务器响应的数据,然后对数据进行逻辑处理,处理好后进行返回;在给响应拦截器传递参数时 需要将请求参数也一起上传;方便进行代码的调式或者其他逻辑处理,所以需要合并数据;然后将合并的参数给响应拦截器。
当接口调用失败时会触发fail回调函数
7.第一个参数:需要合并的目标对象;第二个参数:服务器响应的数据;第三个参数:请求配置以及自定义属性
8.GET POST PUT DELETE四个封装方法
9.对WxRequest进行实例化
10.配置请求拦截器并且发送请求;响应拦截器了解发送前需要做什么
11.将WxRequest实例暴露出去 方便在其他文件中进行使用 export default instance

// 1.使用了微信自带的请求api wx.request
// 2.将wx.request封装到了一个名为request的函数中
// 3.将函数封装到了一个名为wxRequest的类中

// 创建一个WxRequest类
// 通过类的方式进行封装,会让代码更具有复用性
// 也可以方便添加新的属性和方法

class WxRequest{
  // 默认参数对象
  defaults = {
    // 请求基地址
    baseURL:'',
    // 服务器接口地址
    url:'',
    // 请求方式
    method:'GET',
    // 请求参数
    data:null,
    // 请求头
    header: {
    'Content-type': 'application/json' // 设置数据的交互格式
    },
    // 默认超时时间为一分钟
    timeout:100
  }

  // 定义拦截对象,包括请求拦截和响应拦截,方便在请求或响应之前进行处理
  interceptors = {
    // 请求拦截
    request:(config) => config,
    // 响应拦截
    response:(response) => response
  }

  // 用于创建和初始化类的属性和方法
  // params为用户传入的请求配置项
  constructor(params = {}){
    // 使用Object.assign方法合并默认参数以及传递的请求参数
    // 需要传入的参数,会覆盖默认的参数,因此传入的参数放在最后
    this.defaults = Object.assign({},this.defaults,params)
  }
  // request实例方法接受一个对象类型方法
  request(options){
    // 拼接完整的请求路径
    options.url = this.defaults.baseURL + options.url
    // 合并请求参数
    options = {...this.defaults,...options}
    // 发送请求之前添加loading
    wx.showLoading({})
    // 在发送请求之前调用请求拦截器
    options = this.interceptors.request(options)

    console.log(options);
    return new Promise((resolve,reject) => {
      wx.request({
        // 使用拓展运算符将request函数传来的对象参数展开
        ...options,
        // 当接口调用成功就会触发success回调函数
        success:(res) => {

          // 不管接口成功还是失败,都需要调用响应拦截器
          // 响应拦截器需要接受服务器响应的数据,然后对数据进行逻辑处理,处理好后进行返回
          //  在响应拦截器传递参数时,需要将请求参数也一起上传
          // 方便进行代码的调试或者其他逻辑处理,所以需要合并参数
          // 然后将合并的参数给响应拦截器
          // 第一个参数:需要合并的目标对象
          // 第二个参数:服务器响应的数据
          // 第三个参数:请求配置以及自定义属性
          // 不管是请求失败还是请求成功,都会将响应的数据传递给响应拦截器
          // 这个时候合并参数时,就需要追加一个属性:isSuccess
          // 如果属性值为true说明执行了success回调函数
          const mergetRes = Object.assign({},res,{config:options,isSuccess:true})
          // resolve(res)
          resolve(this.interceptors.response(mergetRes))
        },
        // 当接口调用失败就会触发fail回调函数
        fail:(err) => {
          // 如果属性值为false,说明执行了fail回调函数
          const mergetErr = Object.assign({},err,{config:options,isSuccess:false})
          // reject(err)
          reject(this.interceptors.response(mergetErr))
        },
        // 不管promisse请求是否成功
        // 都会执行complete里面的内容
        complete:()=>{
          // 接口调用完成后隐藏loading
          wx.hideLoading()
        }
      })
    })
  }

 1.3封装请求快捷⽅法

⽬前已经完成了 request() 请求⽅法的封装,同时处理了请求参数。 每次发送请求时都使⽤ request() ⽅法即可,但是项⽬中的接⼝地址有很多,不是很简洁。所以我们在 request() 基础上封装⼀些快捷⽅法,简化 request() 的调⽤。

 // 封装GET方法
  get(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'GET',config}))
  }
  // 封装POST实例方法
  post(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'POST',config}))
  }
  // 封装PUT方法
  put(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'PUT',config}))
  }
  // 封装DELETE方法
  delete(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'DELETE',config}))
  }
// 对类进行实例化
const instance = new WxRequest({
  baseURL: 'https://gmall-prod.atguigu.cn/mall-api',
  timeout: 15000
})
// 将 WxRequest 实例进⾏暴露出去,⽅便在其他⽂件中进⾏使⽤
export default instance

 

// 导入在request页面中封装并暴露的instance实例
import instance from '../../utils/http'
// pages/test/test.js
Page({
// 具体阐述按钮点击事件要做什么事情
async handler(){
  //  第一种调用方法:通过.then和.catch接受返回的值
//    instance
//    .request({
//     //  请求地址
//     url:'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
//     // 请求方式
//     method:"GET"
//    })
//    .then((res) => {
//      console.log(res);
//    })
//    .catch((err) => {
//      console.log(err);
//    })

// 第二种调用方法:通过await和async接受返回的值
  // const res = await instance.request({
  //   url:'/index/findBanner',
  //   method:"GET"
  // })

  // 第三种调用方式:通过调用快捷方式接受返回的值
  // const res = await instance.get('/index/findBanner')

  // 调用并传参
  // const res = await instance.get('/index/findBanner',{test:111},
  // {timeout:20000})

  //当前请求地址是获取购物车数据,需要token才行
  const res = await instance.get('/cart/getCartList')

  console.log(res);
 },
}

1.4 定义请求/响应拦截器

为了⽅便统⼀处理请求参数以及服务器响应结果,为 WxRequest 添加拦截器功能,拦截器包括 请求 拦截器 和 响应拦截器

请求拦截器本质上是在请求之前调⽤的函数,⽤来对请求参数进⾏新增和修改

响应拦截器本质上是在响应之后调⽤的函数,⽤来对响应数据做点什么

// 1.使用了微信自带的请求api wx.request
// 2.将wx.request封装到了一个名为request的函数中
// 3.将函数封装到了一个名为wxRequest的类中

// 创建一个WxRequest类
// 通过类的方式进行封装,会让代码更具有复用性
// 也可以方便添加新的属性和方法

class WxRequest{
  // 默认参数对象
  defaults = {
    // 请求基地址
    baseURL:'',
    // 服务器接口地址
    url:'',
    // 请求方式
    method:'GET',
    // 请求参数
    data:null,
    // 请求头
    header: {
    'Content-type': 'application/json' // 设置数据的交互格式
    },
    // 默认超时时间为一分钟
    timeout:100
  }

  // 定义拦截对象,包括请求拦截和响应拦截,方便在请求或响应之前进行处理
  interceptors = {
    // 请求拦截
    request:(config) => config,
    // 响应拦截
    response:(response) => response
  }

  // 用于创建和初始化类的属性和方法
  // params为用户传入的请求配置项
  constructor(params = {}){
    // 使用Object.assign方法合并默认参数以及传递的请求参数
    // 需要传入的参数,会覆盖默认的参数,因此传入的参数放在最后
    this.defaults = Object.assign({},this.defaults,params)
  }
  // request实例方法接受一个对象类型方法
  request(options){
    // 拼接完整的请求路径
    options.url = this.defaults.baseURL + options.url
    // 合并请求参数
    options = {...this.defaults,...options}
    // 发送请求之前添加loading
    wx.showLoading({})
    // 在发送请求之前调用请求拦截器
    options = this.interceptors.request(options)

    console.log(options);
    return new Promise((resolve,reject) => {
      wx.request({
        // 使用拓展运算符将request函数传来的对象参数展开
        ...options,
        // 当接口调用成功就会触发success回调函数
        success:(res) => {

          // 不管接口成功还是失败,都需要调用响应拦截器
          // 响应拦截器需要接受服务器响应的数据,然后对数据进行逻辑处理,处理好后进行返回
          //  在响应拦截器传递参数时,需要将请求参数也一起上传
          // 方便进行代码的调试或者其他逻辑处理,所以需要合并参数
          // 然后将合并的参数给响应拦截器
          // 第一个参数:需要合并的目标对象
          // 第二个参数:服务器响应的数据
          // 第三个参数:请求配置以及自定义属性
          // 不管是请求失败还是请求成功,都会将响应的数据传递给响应拦截器
          // 这个时候合并参数时,就需要追加一个属性:isSuccess
          // 如果属性值为true说明执行了success回调函数
          const mergetRes = Object.assign({},res,{config:options,isSuccess:true})
          // resolve(res)
          resolve(this.interceptors.response(mergetRes))
        },
        // 当接口调用失败就会触发fail回调函数
        fail:(err) => {
          // 如果属性值为false,说明执行了fail回调函数
          const mergetErr = Object.assign({},err,{config:options,isSuccess:false})
          // reject(err)
          reject(this.interceptors.response(mergetErr))
        },
        // 不管promisse请求是否成功
        // 都会执行complete里面的内容
        complete:()=>{
          // 接口调用完成后隐藏loading
          wx.hideLoading()
        }
      })
    })
  }
  // 封装GET方法
  get(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'GET',config}))
  }
  // 封装POST实例方法
  post(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'POST',config}))
  }
  // 封装PUT方法
  put(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'PUT',config}))
  }
  // 封装DELETE方法
  delete(url,data={},config={}){
    return this.request(Object.assign({url,data,method:'DELETE',config}))
  }

}
export default WxRequest

 

不同的请求方式区别

GET请求

用途:用于从服务器请求数据。

数据传递:通过URL的查询字符串传递参数,参数在URL中可见。

安全性:由于参数在URL中可见,因此不适合传输敏感信息。

缓存:GET请求可以被缓存。

POST请求

用途:用于向服务器提交数据,常用于提交表单或上传文件。

数据传递:数据包含在请求体中,不会在URL中显示。

安全性:相比GET请求,POST请求在传输敏感信息时更为安全。

缓存:POST请求不会被缓存。

用途:用于更新服务器上的资源。

DELETE请求:

用途:用于删除服务器上的资源。

幂等性:DELETE请求也是幂等的。

HEAD请求:

用途:与GET请求类似,但只返回响应头,不返回响应体。通常用于检查资源的存在性、获取资源的元信息等。

OPTIONS请求:

用途:用于获取目标资源所支持的通信选项。例如,客户端可以使用它来查看服务器支持的HTTP方法。

// 添加请求拦截器 (在请求发送之前对请求参数进行新增或者修改)
instance.interceptors.request = (config) => {
  // 在实际开发中,有一些接口需要使用访问令牌 token
  // 访问令牌 token 通常是存储到本地
  // 需要先从本地获取到存储的 token
  const token = getStorage('token')

  // 如果本地存在 token,这时候就需要在请求头中添加 token 字段
  if (token) {
    config.header['token'] = token
  }

  // 在发送请求之前做些什么
  return config
}

// 添加响应拦截器 (在服务器响应数据以后,对返回的数据进行逻辑处理)
instance.interceptors.response = async (response) => {
  // 从 response 对象中解构两个数据
  const { isSuccess, data } = response

  // response 服务器响应的数据,只不过数据被 wx.request 进行了一层包装
  // console.log(response)

  // response.config 封装的包里面提供的 config 属性,是请求的参数信息
  // 可以使用请求参数进行代码的调试

  // response.data 服务器真正响应的数据

  // response.isSuccess 判断代码执行了哪一个回调函数
  // isSuccess = true,说明代码执行了 wx.request 方法的 success 回调函数
  // isSuccess = false,说明代码执行了 wx.request 方法的 fail 回调函数
}

 1.5完善请求/响应拦截器

在响应拦截器,我们需要判断是请求成功,还是请求失败,然后进⾏不同的业务逻辑处理。 例如:请求成功以后将数据简化返回,⽹络出现异常则给⽤户进⾏⽹络异常提示。 ⽬前不管请求成功 (success),还是请求失败(fail),都会执⾏响应拦截器 那么怎么判断是请求成功,还是请求失败呢 ? 

封装需求: 1.在实例调⽤的响应拦截中,根据传递的数据进⾏以下的处理:

如果请求成功,将响应成功的数据传递给响应拦截器,同时在传递的数据中新增 isSuccess: true 字段,表示请求成功

如果请求失败,将响应失败的数据传递给响应拦截器,同时在传递的数据中新增 isSuccess: false 字段,表示请求失败

请求拦截器:请求之前调用的函数,用来对请求参数进行新增和修改
响应拦截器:响应之后调用的函数,用来对响应数据进行操作

 

1 // utils/request.js
2  
3 class WxRequest {
4 
5 // coding....
6 
7 request(options) {
8 // coding....
9  
10 // 使⽤ Promise 封装异步请求
11 return new Promise((resolve, reject) => {
12 // 使⽤ wx.request 发起请求
13 wx.request({
14 ...options,
15  
16 // 接⼝调⽤成功的回调函数
17 success: (res) => {
18 // 响应成功以后触发响应拦截器
19 if (this.interceptors.response) {
20 + // 调⽤响应拦截器⽅法,获取到响应拦截器内部返回数据
21 + // success: true 表示服务器成功响应了结果,我们需要对业务状态码进⾏判断
+ res = this.interceptors.response({ response: res, isSuccess: true 
})
22
23 }
24  
25 // 将数据通过 resolve 进⾏返回即可
1.
2.26 resolve(res)
27 },
28  
29 // 接⼝调⽤失败的回调函数
30 fail: (err) => {
31 // 响应失败以后也要执⾏响应拦截器
32 if (this.interceptors.response) {
33 + // isSuccess: false 表示是⽹络超时或其他问题
+ err = this.interceptors.response({ response: err, isSuccess: false
 })
34
35 }
36  
37 // 当请求失败以后,通过 reject 返回错误原因
38 reject(err)
39 }
40 
41 })
42 })
43 }
// 添加请求拦截器 (在请求发送之前对请求参数进行新增或者修改)
instance.interceptors.request = (config) => {
  // 在实际开发中,有一些接口需要使用访问令牌 token
  // 访问令牌 token 通常是存储到本地
  // 需要先从本地获取到存储的 token
  const token = getStorage('token')

  // 如果本地存在 token,这时候就需要在请求头中添加 token 字段
  if (token) {
    config.header['token'] = token
  }

  // 在发送请求之前做些什么
  return config
}

// 添加响应拦截器 (在服务器响应数据以后,对返回的数据进行逻辑处理)
instance.interceptors.response = async (response) => {
  // 从 response 对象中解构两个数据
  const { isSuccess, data } = response

  // response 服务器响应的数据,只不过数据被 wx.request 进行了一层包装
  // console.log(response)

  // response.config 封装的包里面提供的 config 属性,是请求的参数信息
  // 可以使用请求参数进行代码的调试

  // response.data 服务器真正响应的数据

  // response.isSuccess 判断代码执行了哪一个回调函数
  // isSuccess = true,说明代码执行了 wx.request 方法的 success 回调函数
  // isSuccess = false,说明代码执行了 wx.request 方法的 fail 回调函数

  // 如果 isSuccess = false,说明网络出现了问题
  if (!isSuccess) {
    toast({
      title: '网络异常请重试',
      icon: 'error'
    })

    return Promise.reject(response)
  }
// 对响应数据做点什么
// return response
return data
}
// 将 WxRequest 的实例通过模块化的⽅式暴露出去
export default instance

 1.6使⽤请求/响应拦截器

使⽤响应拦截器: 在使⽤ wx.request 发送⽹络请求时。只要成功接收到服务器返回,⽆论 statusCode 是多少,都会进 ⼊ success 回调。 因此开发者根据业务逻辑对返回值进⾏判断。

11 // 响应拦截器
12 instance.interceptors.response = async (response) => {
13  
14 console.log(response);
15  
16 // 从response中结构isSuccess
17 // const { isSuccess } = response
18 const { isSuccess, data } = response
1.
2.
3.19  
20 // 如果isSuccess为false,说明执⾏了fail回调函数
21 // 这时候说明⽹络异常,需要给⽤户提示⽹络异常
22 if (!isSuccess) {
23 wx.showToast({
24 title: '⽹络异常请重试',
25 icon: 'error'
26 })
27  
28 return response
29 }
30  
31 // 判断服务器响应的业务状态码
32 switch(data.code){
33  
34 // 如果后端返回的业务状态码等于200,说明请求成功,服务器成功响应了数据
35 case 200:
36 // 对服务器响应数据做点什么
37 return data
38  
39 // 如果返回的业务状态码等于208,说明没有token,或者token失效
40 // 就需要让⽤户登录或者重新登录
41 case 208:
42 const res = await modal({
43 content:'鉴权失败,请重新登录',
44 showCancel:false // 不显示取消按钮
45 })
46 if(res){
47 // 清除之前失效的token,同时要清除本地存储的全部信息
48 clearStorage()
49 wx.navigateTo({
50 url: '/pages/login/login',
51 })
52 }
53 return Promise.reject(response)
54 
55 default:
56 toast({
57 title:'程序出现异常,请联系客服或稍后重试'
58 })
59 return Promise.reject(response)
60 }
61  
62 // 对响应数据做点什么
63 // return response
64 // return data
65 }
66  
67 // 将 WxRequest 的实例通过模块化的⽅式暴露出去
68 export default instance

 1.8请求封装-添加并发请求

前端并发请求是指在前端⻚⾯同时向后端发起多个请求的情况。当⼀个⻚⾯需要请求多个接⼝获取数 据时,为了提⾼⻚⾯的加载速度和⽤户体验,可以同时发起多个请求,这些请求之间就是并发的关 系。

1使⽤ async 和 await ⽅式

2使⽤ Promise.all() ⽅式

1 <!--pages/test/test.wxml-->
2  
3 <view class="box">
 <button type="warn" size="mini" plain bindtap="AllHandler">测试并发请求
</button>
4
5 </view>

 

1 // test/test.js
2  
3 page({
4 // 演示通过 async 和 await ⽅式同步发起多个请求
5 // async 和 await 能够控制异步任务以同步的流程来执⾏// async和awiat⽅式发起多个请求
6 // 当第⼀个请求结束以后,才能够发起第⼆个请求
7 // 当前⼀个请求结束以后,才能够发起下⼀个请求
8 // 会造成请求的阻塞,从⽽影响⻚⾯的渲染速度
9 async AllHandler(){
10 await instance.get('/index/findBanner')
11 await instance.get('/index/findCategory1')
12 await instance.get('/index/findBanner')
13 await instance.get('/index/findCategory1')
14 
15 // 演示通过 Promise.all 同时发送多个请求
16 // Promise.all 能够将多个请求同时进⾏发送
17 // Promise.all 能够将多个异步请求同时进⾏发售,也就是并⾏发送
18 // 并不会造成请求的阻塞,从⽽不会影响⻚⾯的渲染速度
 await 
Promise.all([instance.get('/index/findBanner'),instance.get('/index/findCategory
1'),
19
20 instance.get('/index/findBanner'),instance.get('/index/findCategory1')])
21 
22 })
class WxRequest{
  code...
// 用来处理并发请求
  all(...promise){
  // 通过展开运算符接受传递的参数
  // 展开运算符会将传入的参数转为数组
  console.log(promise);
  return Promise.all(promise)
}
}

1.9添加loading

在封装时添加 loading 效果,从⽽提⾼⽤户使⽤体验

在请求发送之前,需要通过 wx.showLoading 展示 loading 效果

当服务器响应数据以后,需要调⽤ wx.hideLoading 隐藏 loading 效果

1 // request.js
2  
3 class WxRequest {
4 request(options) {
5  
6 // 拼接完整的请求地址
7 options.url = this.defaults.baseURL + options.url
8  
9 // 合并请求参数
10 options = { ...this.defaults, ...options }
11  
12 + // 发送请求之前添加loading
13 + wx.showLoading()
14  
15 // 在发送请求之前调⽤请求拦截器,新增或修改请求参数
16 options = this.interceptors.request(options)
17  
18 console.log(options);
19  
20 return new Promise((resolve, reject) => {
21  
22 wx.request({
23  
24 // 使⽤拓展运算符将request函数传来的对象参数展开
25 ...options,
26  
27 // 当接⼝调⽤成功就会触发success回调函数
28 success: (res) => {
29  
30 // 不管是请求失败还是请求成功,都已经将响应的数据传递给了响应拦截器
31 // 这时候再合并参数的时候,追加⼀个属性:isSuccess
32 // 如果属性值为true,说明执⾏了success回调函数
33 // 如果属性值为false,说明执⾏了fail回调函数
 const mergeRes = Object.assign({}, res, { config: 
options,isSuccess:true })
34
35 resolve(this.interceptors.response(mergeRes))
36  
37 },
38  
39 // 当接⼝调⽤失败时会触发fail回调函数
40 fail: (err) => {
 const mergeErr = Object.assign({}, err, { iconfig: 
options,isSuccess:false })
41
42 // 不管接⼝成功还是失败,都需要调⽤响应拦截器
43 err = this.interceptors.response(mergeErr)
44 reject(err)
45 },
46  
47 + complete:() => {
48 + // 接⼝调⽤完成后隐藏loading
49 + wx.hideLoading()
50 }
51 })
52 })
53 } 
54 }

 1.test.js代码

1 // 导⼊模块、包提供的类
2 import WxRequest from 'mina-request'
3 // 导⼊封装的本地存储操作模块
4 import { getStorage, clearStorage } from './storage'
5 // 导⼊封装的增强 API
6 import { toast, modal } from './extendApi'
7  
8 // 对类进⾏实例化
9 const instance = new WxRequest({
10 baseURL: 'https://gmall-prod.atguigu.cn/mall-api',
11 timeout: 15000
12 })
13  
14 // 添加请求拦截器 (在请求发送之前对请求参数进⾏新增或者修改)
15 instance.interceptors.request = (config) => {
16 // 在实际开发中,有⼀些接⼝需要使⽤访问令牌 token
17 // 访问令牌 token 通常是存储到本地
18 // 需要先从本地获取到存储的 token
19 const token = getStorage('token')
20  
21 // 如果本地存在 token,这时候就需要在请求头中添加 token 字段
22 if (token) {
23 config.header['token'] = token
24 }
25  26 // 在发送请求之前做些什么
27 return config
28 }
29  
30 // 添加响应拦截器 (在服务器响应数据以后,对返回的数据进⾏逻辑处理)
31 instance.interceptors.response = async (response) => {
32 // 从 response 对象中解构两个数据
33 const { isSuccess, data } = response
34  
35 // response 服务器响应的数据,只不过数据被 wx.request 进⾏了⼀层包装
36 // console.log(response)
37  
38 // response.config 封装的包⾥⾯提供的 config 属性,是请求的参数信息
39 // 可以使⽤请求参数进⾏代码的调试
40  
41 // response.data 服务器真正响应的数据
42  
43 // response.isSuccess 判断代码执⾏了哪⼀个回调函数
44 // isSuccess = true,说明代码执⾏了 wx.request ⽅法的 success 回调函数
45 // isSuccess = false,说明代码执⾏了 wx.request ⽅法的 fail 回调函数
46  
47 // 如果 isSuccess = false,说明⽹络出现了问题
48 if (!isSuccess) {
49 toast({
50 title: '⽹络异常请重试',
51 icon: 'error'
52 })
53  
54 return Promise.reject(response)
55 }
56  
57 // 如果 isSuccess = true,说明代码执⾏到了 success 回调函数
58 // 需要开发者对返回的参数进⾏逻辑判断
59 // 需要对后端返回的业务状态码进⾏判断
60 // 业务状态码 === 200,接⼝调⽤成功,服务器成功返回了数据
61 // 业务状态码 === 208,没有 token 或者 token 失效,需要让⽤户重新进⾏登录
62 // 业务状态码既不等于 200,也不等于 208,说明出现了其他异常,需要给⽤户统⼀进⾏提示
63 switch (data.code) {
64 case 200:65 // 接⼝调⽤成功,服务器成功返回了数据,只需要将数据简化以后返回即可
66 return data
67  
68 case 208:
69 const res = await modal({
70 content: '鉴权失败,请重新登录',
71 showCancel: false
72 })
73  
74 if (res) {
75 // 既然⽤户需要重新进⾏登录,就需要把之前⽤户存储的信息(过期的 token) 进⾏清除
76 clearStorage()
77  
78 wx.navigateTo({
79 url: '/pages/login/login'
80 })
81 }
82  
83 return Promise.reject(response)
84  
85 default:
86 toast({
87 title: '程序出现异常,请联系客服或稍后重试!'
88 })
89 return Promise.reject(response)
90 }
91  
92 // return response
93 }
94  
95 // 导出实例
96 export default instance

 1.10接⼝调⽤⽅式说明

开发中,我们会将所有的⽹络请求⽅法放置在 api ⽬录下统⼀管理,然后按照模块功能来划分成对应 的⽂件,在⽂件中将接⼝封装成⼀个个⽅法单独导出

1 // index.js
2  
3 // 导⼊封装的⽹络请求模块实例
4  
5 import http from '../utils/http'
6  
7 // export const reqSwiperData = () => {
8 // return http.get('/index/findBanner')
9 // }
10  
11 export const reqSwiperData = () => http.get('/index/findBanner')
1 // test/test.js
2  
3 // 导⼊接⼝API函数 
4 import {reqSwiperData} from '../../api/index'
5  
6 Page({
7  
8 // 点击按钮触发 handler ⽅法
9 async handler() {
10  
11 const res = await reqSwiperData()
12  
13 console.log(res);
14 
15 })

8.首页页面

1.获取⾸⻚数据

1 // api.index.js
2  
3 // 导⼊封装的 ⽹络请求模块实例
4 import http from '../utils/http'
5  
6 export const reqIndexData = () => {
7 // 通过并发请求获取⾸⻚的数据,提升⻚⾯的渲染速度
8  
9 // 通过 Promise.all 进⾏并发请求
10 // return Promise.all([
11 // http.get('/index/findBanner'),
12 // http.get('/index/findCategory1'),
13 // http.get('/index/advertisement'),
14 // http.get('/index/findListGoods'),
15 // http.get('/index/findRecommendGoods')
16 // ])
17  
18 // 是使⽤封装的 all ⽅法发送请求
19 // 这两种⽅式都可以
20 return http.all(
21 http.get('/index/findBanner'),
22 http.get('/index/findCategory1'),
23 http.get('/index/advertisement'),
24 http.get('/index/findListGoods'),
25 http.get('/index/findRecommendGoods')
26 )
27 }
// 导入接口api
import { reqIndexData } from '../../api/index'
Page({
  // 初始化数据
  data:{
    bannerList:[],//轮播图数据
    categotyList:[],//分类数据
    activeList:[],//活动广告
    hotList:[],//人气推荐
    guessList:[]//猜你喜欢
  },
  // 获取首页数据
  async getIndexData(){
    const res = await reqIndexData()
    console.log(res);
    // 在获取数据以后,对数据进行赋值
    this.setData({
      bannerList:res[0].data,//轮播图数据
      categotyList:res[1].data,//分类数据
      activeList:res[2].data,//活动广告
      hotList:res[3].data,//人气推荐
      guessList:res[4].data//猜你喜欢
    })
  },
  // 监听页面加载
  onLoad(){
    this.getIndexData()
  }
})

 

<view class="index-container">
  <!-- 首页背景图 -->
  <view class="window-bgc"></view>
  <!-- 页面主体区域 -->
  <view class="container">
  <!-- bannerList、cateList是原本的data数据 -->
  <!-- {{bannerList}}、{{categoryList}}是从服务器中获得的数据 -->
    <!-- 轮播图区域 -->
    <banner bannerList = "{{ bannerList }}"/>
    <!-- 导航区域 -->
    <entrance cateList = "{{ categotyList }}"/>
    <!-- 广告区域 -->
  <view class="adver">
    <view class="adver-left">
      <navigator url="/pages/goods/list/list?category2Id={{activeList[0].category2Id}}">
        <image src="{{ activeList[0].imageUrl }}" mode="widthFix"/>
      </navigator>
    </view>
    <view class="adver-right">
      <view>
        <navigator url="/pages/goods/list/list?category2Id={{activeList[1].category2Id}}">
          <image src="{{ activeList[1].imageUrl }}" mode="widthFix"/>
        </navigator>
      </view>
      <view>
        <navigator url="/pages/goods/list/list?category2Id={{activeList[2].category2Id}}">
          <image src="{{ activeList[2].imageUrl }}" mode="widthFix"/>
        </navigator>
      </view>
    </view>
  </view>
    <!-- 商品列表 -->
    <goods-list title="猜你喜欢"  list="{{ guessList }}"></goods-list>
    <goods-list title="人气推荐" list="{{ hotList }}"></goods-list>
  </view>
</view>

 2.分析轮播图区域并渲染

轮播图区域采⽤组件化⽅式开发,我们在 index ⽬录下新建 banner ⽂件夹,⾥⾯存放轮播图组件。 在 index/index.json ⽂件中导⼊组件,然后将组件当成标签进⾏使⽤。

{
  "usingComponents": {
    "banner": "./banner/banner",
    "entrance": "./entrance/entrance",
    "goods-list": "../../components/goods-list/goods-list"
  }
}
Component({
  // 组件的属性列表
  properties:{
    // 轮播图数据
    bannerList: {
      type: Array,
      value: [
        '../../../assets/banner/banner-1.jpg',
        '../../../assets/banner/banner-2.jpg',
        '../../../assets/banner/banner-3.jpg'
      ]
    }
  },
  /**
   * 组件的初始数据
   */
  data:{
    // 被激活的轮播图索引,默认是0
    activeIndex:0
  },
  /**
   * 
   */
  methods:{
    getSwiperIndex(event){
      // console.log(event);
      const {current} = event.detail;
      this.setData({
        // 将当前的轮播图索引设置为activeInddex
        activeIndex:current
      })
    }
  }
})

 

<!--pages/index/banner/banner.wxml-->
<!-- 轮播图 -->
<view class="swiper-box">
  <navigator class="navigator" url="/pages/goods/detail/detail?goodId={{ item.id }}">
  <swiper autoplay class="swiper" indicator-active-color="#FF734C" interval="2000" duration="1000" indicator-color="rgba(0,0,0, .3)"
  bindchange="getSwiperIndex"
  >
    <block wx:for="{{ bannerList }}" wx:key="index">
      <swiper-item class="swiper-item">
        <image class="img" src="{{ item.imageUrl }}"></image>
      </swiper-item>
    </block>
  </swiper>
</navigator>
  <!-- 轮播图的面板指示点,因为面板指示点不支持,所以我们只能通过自定义结构的方式 -->
  <view class="indicator">
  <!-- active 类名:当前被激活的面板指示点颜色 -->
  <!-- rectangle 类名:默认的面板指示点颜色 -->
    <text 
      wx:for="{{bannerList.length}}" 
      wx:key="id" 
      class="{{ 'active rectangle' }}"
    ></text>
  </view>
</view>

 

3渲染分类导航

Component({
  // 组件的属性列表
  properties:{
    // 分类列表
    cateList: {
      type: Array,
      value: []
    }
  }
})
 渲染导航分类结构
<!--pages/index/entrance/entrance.wxml-->
<view class="nav-list">
<!-- 一级分类导航容器 -->
<view wx:for="{{ cateList }}" wx:key="index" class="nav-item {{ index >= 5 ? 'small' : '' }}">
<!-- 导航链接 -->
  <navigator url="/pages/goods/list/list?category1Id={{item.id}}" class="navigator-nav">
    <image src="{{ item.imageUrl }}" class="nav-img"/>
    <text class="nav-text">{{ item.name }}</text>
  </navigator>
</view>
</view>
 导航分类结构样式调整
/* pages/index/entrance/entrance.wxss */
.nav-list {
  margin: 20rpx;
  border-radius: 18rpx;
  padding: 10px 0px 10px 10px;
  background-color: white;

  // 设置弹性布局
  display: flex;
  // 设置换行
  flex-wrap: wrap;
  .nav-item{
    .navigator-nav{
      display: flex;
      // 更改主轴方向
      // 由默认的横向排列更改为纵向排列
      flex-direction: column;
      align-items: center;
      justify-content: center;
      margin-right: 10px;
      margin-top: 10px;
    }
    .nav-text{
      margin-top: 4px;
      font-size: 12px;
    }
    .nav-img{
      width: 66rpx;
      height: 66rpx;
    }
    &.small {
      margin-top: 36rpx;
      .nav-img{
        width: 50rpx !important;
        height: 50rpx !important;
      }
    }
  }
}

 

 4.渲染活动区域

1 // pages/index/index.html
2  
3 <!-- ⼴告区域 -->
4 <view class="adver">
5 <view class="adver-left">
+ <navigator url="/pages/goods/list/list?category2Id={{ 
activeList[0].category2Id }}">
6
7 + <image src="{{ activeList[0].imageUrl }}" mode="widthFix" />
8 + </navigator>
9 </view>
10  
11 <view class="adver-right">
12 <view>
+ <navigator url="/pages/goods/list/list?category2Id={{ 
activeList[1].category2Id }}">
13
14 + <image src="{{ activeList[1].imageUrl }}" mode="widthFix" />
15 + </navigator>
16 </view>
17 <view>
+ <navigator url="/pages/goods/list/list?category2Id={{ 
activeList[2].category2Id }}">
18
19 + <image src="{{ activeList[2].imageUrl }}" mode="widthFix" />
20 + </navigator>
21 </view>
22 </view>
23 </view>

 

5.猜你喜欢+⼈⽓推荐区域渲染

接收⾸⻚传递的 list 数据
Component({
  /**
  * 组件的属性列表
  */
  properties: {
    // 列表标题
    title: {
     type: String,
     value: '',
    },
   // 传递的列表数据
   list: {
   type: Array,
   value: []
   }
   },
   /**
   * 组件的初始数据
   */
   data: {}, 
     /**
     * 组件的⽅法列表
     */
    methods: {}
})
 遍历  goods-item  组件,并将数据传递给  goods-item 
<!--components/goods-list/goods-list.wxml-->
<view class="goods_container" wx:if="{{ list.length }}">
  <!-- 标题 -->
  <view class="goods_title">{{title}}</view>

  <!-- 列表区域 -->
  <view class="goods_card_list">
      <goods-card wx:for="{{ list }}" wx:key="id" goodItem="{{ item }}"/>
  </view>
  <!-- 查看更多 -->
  <view class="goods_more">
    <navigator url="" class="goods_more_btn" url="/pages/goods/list/list" hover-class="navigator-hover" open-type="navigate">
      查看更多
    </navigator>
  </view>
</view>
{
  "component": true,
  "usingComponents": {
    "goods-card":"/components/goods-card/goods-card"
  }
}
将数据传递给  goods-item  组件
Component({
  /**
   * 组建的属性列表
   */
  properties:{
    // 每一项商品的数据
    goodItem: {
      type:Object,
      value: {}
    }
  },
  /**
   * 组件的初始数据
   */
  data: {},
  /**
   * 组建的方法列表
   */
  methods: {}
})
 将数据传递给  goods-item  组件
<!--components/goods-card/goods-card.wxml-->
<view class="goods_card_container">
<!-- 图片 -->
  <navigator class="navigator_nav" url="/pages/goods/detail/detail?goodsId={{goodItem.id}}">
    <image src="{{ goodItem.imageUrl }}" mode="widthFix" class="goods_img"/>
  <!-- 详细信息 -->
  <view class="goods_item_info">
    <!-- 商品名称 -->
    <text class="goods_item_info_name">{{ goodItem.name }}</text>
    <!-- 商品描述 -->
    <text class="goods_item_info_promo">{{ goodItem.floralLanguage }}</text>
    <!-- 商品价格 -->
    <view class="goods_item_info_bottom">
      <view class="goods_item_info_price">
        <text class="text">¥</text>{{ goodItem.price }}
      </view>
      <view class="goods_item_info_origin_price">
        <text class="text">¥</text>{{goodItem.marketPrice}}
      </view>
      <!-- 加入购物车图片 -->
      <view class="goods_item_info_btn">
        <image class="goods_image" src="/static/images/buybtn.png" mode=""/>
      </view>
    </view>
  </view>
  </navigator>
</view>

 9.分类页面

1.渲染分类页面
// 导入已经封装好的请求api
import {reqCategoryData} from '../../api/category'

Page({
  data:{
    categoryList:[],
    //设置被选择的高亮类
    // 默认是第0个
    activeIndex:0
  },
  // 实现一级分类的切换效果
  updateAcitve(event){
    // console.log(event);
    // 打印元素的下标
    // console.log(event.currentTarget.dataset);
    // 讲点击元素的下表结构出来
    const {index} = event.currentTarget.dataset;
    console.log(index);
    this.setData({
      activeIndex:index
    })
  },
  async getCategoryData(){
    // 调用接口获取分类数据
    const res = await reqCategoryData()
    // 将分类数据打印出来
    console.log(res);

    this.setData({
      categoryList:res.data
    })
  },
  // 监听页面加载
  onLoad(){
    this.getCategoryData()
  }
})
<!--pages/category/category.wxml-->
<view>
  <view class="category-container">
    <!-- 左侧的滚动视图区域 -->
    <scroll-view class="category-left-view" scroll-y>
      <!-- active:被选中的内容 -->
      <view class="left-view-item {{ activeIndex === index ? 'active' : '' }}" wx:for="{{categoryList}}" wx:key="id" bindtap="updateAcitve" data-index="{{index}}">
        {{ item.name}}
      </view>
    </scroll-view>
    <!-- 右侧的滚动视图区域  -->
    <scroll-view class="category-right-view" scroll-y>
      <!-- 二级分类 -->
      <view class="test">
        <view wx:for="{{ 10 }}" wx:key="index" class="right-view-item">
          <navigator class="navigator" url="">
            <image class="" src="../../assets/images/cate-1.png" mode="" />
            <text class="goods_item_name">真情告白</text>
          </navigator>
        </view>
      </view>
    </scroll-view>
  </view>
</view>

  • 24
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值