慕尚花坊小程序笔记二

一.购物车页面

vant组件库引入

在vant-weapp找到提交订单栏,"van-submit-bar": "@vant/weapp/submit-bar/index"将这些代码复制到app.json中的"usingComponents": {}里面

 "usingComponents": {
    "van-action-sheet": "@vant/weapp/action-sheet/index"
  }

card.wxml配置

<view bindtap="onSwipeCellPage">
  <!-- 购物车列表结构 -->
  <view
    wx:if="{{ token && cartList.length }}"
    class="container goods-wrap"
    bindtap="onSwipeCellPageTap"
  >
    <view class="goods-item" wx:for="{{ cartList }}" wx:key="goodsId">
      <van-swipe-cell
        class="goods-swipe"
        right-width="{{ 65 }}"
        id="swipe-cell-{{ item.goodsId }}"
        bind:open="swipeCellOpen"
        bind:click="onSwipeCellClick"
      >
        <van-cell-group border="{{ false }}">
          <view class="goods-info">
            <view class="left">
              <van-checkbox
                checked-color="#FA4126"
                value="{{ item.isChecked }}"
                bindchange="updateChecked"
                data-id="{{ item.goodsId }}"
                data-index="{{ index }}"
              ></van-checkbox>
            </view>
            <view class="mid">
              <image class="img" src="{{ item.imageUrl }}" />
            </view>
            <view class="right">
              <view class="title"> {{ item.name }} </view>
              <view class="buy">
                <view class="price">
                  <view class="symbol">¥</view>
                  <view class="num">{{ item.price }}</view>
                </view>
                <view class="buy-btn">
                  <van-stepper
                    min="1"
                    max="200"
                    integer
                    value="{{ item.count }}"
                    data-id="{{ item.goodsId }}"
                    data-index="{{ index }}"
                    data-oldbuynum="{{ item.count }}"
                    bindchange="changeBuyNum"
                  />
                </view>
              </view>
            </view>
          </view>
        </van-cell-group>
        <view
          slot="right"
          class="van-swipe-cell__right"
          bindtap="delCartGoods"
          data-id="{{ item.goodsId }}"
          >删除</view
        >
      </van-swipe-cell>
    </view>
  </view>

  <!-- 购物车列表为空展示的结构 -->
  <van-empty wx:else description="{{ emptyDes }}">
    <navigator
      url="/pages/index/index"
      open-type="switchTab"
      wx:if="{{ token && cartList.length === 0 }}"
    >
      <van-button round type="danger" class="bottom-button">去购物</van-button>
    </navigator>

    <navigator url="/pages/login/login" wx:else>
      <van-button round type="danger" class="bottom-button">去登录</van-button>
    </navigator>
  </van-empty>

  <!-- 底部工具栏 -->
  <!-- 底部工具栏组件展示价格,默认是以 分 的形式进行展示,如果需要以 元 的方式进行展示 -->
  <van-submit-bar
    wx:if="{{ cartList.length }}"
    price="{{ totalPrice * 100 }}"
    button-text="去结算"
    tip="{{ true }}"
    bind:submit="toOrder"
  >
    <van-checkbox
      value="{{ selectAllStatus }}"
      checked-color="#FA4126"
      bindchange="selectAllStatus"
    >
      全选
    </van-checkbox>
  </van-submit-bar>
</view>

card.scss 样式配置

// 商品列表样式
.goods-wrap {
  padding: 16rpx 16rpx 100rpx 16rpx;

  .goods-item {
    .goods-swipe {
      width: 100%;

      .goods-info {
        display: flex;
        align-items: center;
        padding: 24rpx 16rpx;
        border-radius: 16rpx;
        margin-bottom: 16rpx;
        background-color: white;
        box-sizing: border-box;
        transition: transform 1s cubic-bezier(0.18, 0.89, 0.32, 1) !important;

        .left {
          /* width: 56px; */
          display: flex;
          align-items: center;
          justify-content: center;
        }

        .mid {
          width: 114px;
          height: 125px;

          .img {
            height: 100%;
          }
        }

        .right {
          height: 125px;
          flex: 1;
          display: flex;
          flex-direction: column;
          justify-content: space-between;
          margin-left: 10px;

          .title {
            flex: 1;
            flex-shrink: 0;
            font-size: 26rpx;
            color: #333;
            line-height: 44rpx;
            font-weight: 400;
            overflow: hidden;
            word-break: break-word;
          }

          .buy {
            display: flex;
            justify-content: space-between;

            .price {
              display: flex;
              color: #fa4126;
              font-size: 36rpx;

              .symbol {
                font-size: 10px;
                margin-right: 2px;
                margin-top: 8px;
              }
            }
          }
        }
      }

      .van-swipe-cell__right {
        background-color: #fa4126;
        text-align: center;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 130rpx;
        color: #fff;
        font-size: 24rpx;
        height: 100%;
      }
    }
  }
}

// 提交订单栏样式
.submit-footer {
  display: flex;
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  background-color: white;
  padding: 12px 8px;
  align-items: center;
  justify-content: space-between;
  z-index: 10;

  .right {
    display: flex;
    margin-right: 16px;
    align-items: center;
    justify-content: center;
  }
}

效果展示图 

二.我的页面

my.js配置

// pages/info/info.js

import { ComponentWithStore } from 'mobx-miniprogram-bindings'
import { userStore } from '@/stores/userstore'

ComponentWithStore({
  // 页面的初始数据
  data: {
    // 初始化第二个面板数据
    initpanel: [
      {
        url: '/modules/orderPayModule/pages/order/list/list',
        title: '商品订单',
        iconfont: 'icon-dingdan'
      },
      {
        url: '/modules/orderPayModule/pages/order/list/list',
        title: '礼品卡订单',
        iconfont: 'icon-lipinka'
      },
      {
        url: '/modules/orderPayModule/pages/order/list/list',
        title: '退款/售后',
        iconfont: 'icon-tuikuan'
      }
    ]
  },

  storeBindings: {
    store: userStore,
    fields: ['token', 'userInfo']
  },

  methods: {
    // 跳转到登录页面
    toLoginPage() {
      wx.navigateTo({
        url: '/pages/login/login'
      })
    }
  }
})

my.wxml配置

<!--pages/info/info.wxml-->
<view class="container">
  <!-- 顶部展示图 -->
  <view class="top-show">
    <image mode="widthFix" class="top-show-img" src="/assets/images/banner.jpg"></image>
  </view>

  <view class="bottom-show">
    <!-- 未登录面板 -->
    <view wx:if="{{ !token }}" class="user-container section" bindtap="toLoginPage">
      <view class="avatar-container">
        <image src="/assets/images/avatar.png"></image>
        <view class="no-login">
          <text class="ellipsis">未登录</text>
          <text>点击授权登录</text>
        </view>
      </view>
    </view>

    <!-- 登录以后得面板 -->
    <view wx:else class="user-container section">
      <view class="avatar-container">
        <image src="{{ userInfo.headimgurl }}"></image>
        <view class="no-login">
          <text class="ellipsis">{{ userInfo.nickname }}</text>
        </view>
      </view>
      <view class="setting">
        <navigator url="/modules/settingModule/pages/settings/settings"> 设置 </navigator>
      </view>
    </view>

    <!-- 订单面板 -->
    <view class="order section">
      <view class="order-title-wrap">
        <text class="title">我的订单</text>
        <text class="more">查看更多></text>
      </view>

      <view class="order-content-wrap">
        <view class="order-content-item" wx:for="{{ initpanel }}" wx:key="index">
          <navigator url="{{ token ? item.url : '/pages/login/login' }}">
            <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>
</view>

my.scss样式配置

.container {
  padding: 0rpx !important;
}

.top-show {
  width: 100%;
  height: 360rpx;

  .top-show-img {
    width: 100%;
    height: 100%;
  }
}

.bottom-show {
  margin: 0 16rpx;

  .section {
    background-color: #fff;
    border-radius: 20rpx;
    padding: 20rpx;
  }

  .user-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: -86rpx;
    color: #999;

    .avatar-container {
      display: flex;
      align-items: center;

      image {
        width: 120rpx;
        height: 120rpx;
        border-radius: 50%;
        margin-right: 20rpx;
      }

      .no-login {
        display: flex;
        flex-direction: column;
        font-size: 24rpx;

        text:first-child {
          font-size: 28rpx;
        }

        .ellipsis {
          width: 400rpx;
          overflow: hidden;
          text-overflow: ellipsis;
          overflow: hidden;
          white-space: nowrap;
        }
      }
    }
  }

  .order {
    background-color: #fff;
    margin-top: 20rpx;

    .order-title-wrap,
    .order-content-wrap {
      padding: 20rpx;
      display: flex;
      justify-content: space-between;
    }

    .order-title-wrap {
      .title {
        color: #444;
        // font-weight: 700;
      }

      .more {
        color: #ccc;
        font-size: 24rpx;
      }
    }

    .order-content-wrap {
      display: flex;

      .iconfont {
        font-size: 60rpx;
        text-align: center;
      }

      text {
        font-size: 25rpx;
        margin-top: 20rpx;
      }
    }

    .order-content-item {
      display: flex;
      flex-direction: column;
      align-items: center;
    }
  }

  .after-scale {
    margin-top: 30rpx;

    .order-title-wrap {
      line-height: 50rpx;
    }

    .after-scale-item {
      display: flex;
      margin: 25rpx 15rpx;
      color: #999;
      line-height: 50rpx;

      text {
        font-size: 25rpx;
        margin-left: 20rpx;
      }

      .iconfont {
        color: #a2b364;
      }
    }
  }

  .info-footer {
    height: 100rpx;
    line-height: 100rpx;
    text-align: center;
    color: #aaa;
    font-size: 25rpx;
  }
}

 

效果展示图 

三.商品列表页面

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属性控制文字的显示与隐藏 -->
  <!-- 当数据加载完毕,isFinsh为trun,!isFinsh为false,则这句话不隐藏,用户能看到这句话 -->
  <view class="finish" hidden="{{ !isFinsh}}">数据加载完毕</view>
</view>

list.scss样式配置 

.container {
 
  .goods-list {
    padding: 15rpx;
    display: flex;
    //设置换行
    flex-wrap: wrap;
    //设置元素在主轴上的排列方式
    justify-content: space-between;
  }
 
  .finish {
    // 文本居中对齐
    text-align: center;
    font-size: 25rpx;
    color: green;
    line-height: 70rpx;
    border-top: 1px solid black;
  }
}

 效果展示图

四.商品细节页面

detail.js配置

// pages/detail/detail.js
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
 
  },
  // 点击按钮事件,控制面板显示
  handelSheet(){
    this.setData({
      show:true
    })
  },
 
  onClose(){
    this.setData({
      show:false
    })
  },

detail.wxml配置 

<!--pages/detail/detail.wxml-->
<view class="container">
  <!-- 商品大图 -->
  <view class="banner-img">
    <image src="../../assets/images/floor-img.jpg" mode="" />
  </view>
 
  <!-- 商品基本信息 -->
  <view class="content">
    <!-- 商品的价钱 -->
    <view class="price">
      <view class="price-num">¥299</view>
      <view class="price-origin-unm">¥399</view>
    </view>
    <!-- 商品的标题 -->
    <view class="title">99支红玫瑰/99支红玫瑰/99支红玫瑰</view>
    <!-- 详细信息 -->
    <view class="info">爱她,就送她99只玫瑰</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" text="主页" info="" />
    </navigator>
 
    <navigator url="/pages/cart/cart" open-type="switchTab">
      <van-goods-action-icon icon="cart-o" text="购物车" info="" />
    </navigator>
 
    <navigator url="/pages/my/my" open-type="switchTab">
      <van-goods-action-icon icon="user-circle-o" text="我的" />
    </navigator>
 
    <van-goods-action-button text="加入购物车" type="warning" bindtap="handelSheet" />
 
    <!-- handelSheet为点击按钮事件 -->
    <van-goods-action-button text="立即购买" bindtap="handelSheet" />
  </van-goods-action>
 
  <!-- 自定义盒子 -->
  <!-- bind:close为面板关闭事件 -->
  <van-action-sheet show="{{ show }}" title="" bind:close="onClose">
    <view class="sheet-container">
      <!-- 图片区域 -->
      <view class="img">
        <image src="../../assets/images/floor-img.jpg" mode="" />
      </view>
      <!-- 商品基本信息区域 -->
      <view class="baseInfo">
        <!-- 商品名称 -->
        <view class="title">买花就送女友/送爱人/送老婆</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">
    <!-- round 设置圆角弧度 -->
      <van-button type="primary" round size="large">确定</van-button>  
    </view>
 
 
 
 
  
  </van-action-sheet>
</view>

detail.scss样式配置

.container {
  background-color: whitesmoke;
  height: 100vh;
 
  .banner-img {
    // 高度
    height: 800rpx;
    image {
      height: 100%;
    }
  }
 
  // 商品基本信息
  .content {
    background-color: white;
    // margin 设置框外边距
    margin: 0 46rpx;
    // padding 设置内边距
    padding: 40rpx; //框内
    // 设置圆角弧度
    border-radius: 20rpx;
 
    // 相对于原本的位置发生改变是相对定位
    // 相对于父盒子位置发生改变是绝对定位
    position: relative; //相对定位
    top: -200rpx; //上下平移
 
 
    .price {
      // 将块级元素一行显示
      display: flex;
 
      // 299
      .price-num {
        color: red;
        // 字体加粗
        font-weight: bolder;
        // 字体大小
        font-size: 18px;
      }
 
      // 399
      .price-origin-unm {
 
        color: #b4babf;
        text-decoration: line-through; //399数字有横线
        // 字体大小
        font-size: 12px;
        margin-left: 15px; //399离299距离
        margin-top: 5px; // 399数字上下
      }
    }
 
    .title {
      // 溢出隐藏
      overflow: hidden;
      // 超过一行就算溢出
      white-space: nowrap;
      // 溢出之后的文本
      text-overflow: ellipsis;
      font-size: 16px; // 字体大小
      font-weight: bolder; // 字体加粗
    }
 
    .info {
      color: #b4babf;
      // 溢出隐藏
      overflow: hidden;
      // 超过一行就算溢出
      white-space: nowrap;
      // 溢出之后的文本
      text-overflow: ellipsis;
      font-size: 12px; // 字体大小
    }
  }
 
  // 商品详细信息
  .detail {
    background-color: white;
    padding: 20rpx; // padding 设置内边距
    margin: -150rpx 20rpx 0 20rpx;
    border-radius: 20rpx; // 设置圆角弧度
 
    image {
      width: 100%; // 框
      height: 700rpx; //高
    }
  }
 
  .sheet-container {
    margin: 20rpx; // margin 设置框外边距
    padding: 20rpx; // padding 设置内边距
    border-radius: 20rpx;
    display: flex;
 
    .img {
      height: 400rpx;
      width: 350rpx;
 
      image {
        width: 100%;
        height: 100%;
      }
    }
 
    .buy {
      display: flex;
 
      .price {
        display: flex;
        color: red;
      }
    }
 
    .baseInfo {
      display: flex;
      // 设置主轴方向
      flex-direction: column;
      // 设置主轴上的排序列方式
      justify-content: space-between;
      margin-left: 20rpx;
 
      .title {
        font-size: 14px;  // 字体大小
      }
    }
  }
 
  .textArea {
    background-color: white;
    margin: 0 20rpx;
 
    .title {
      margin-right: 20rpx; //左边距
      margin-bottom: 20rpx;
    }
 
    .box {
      background-color: whitesmoke;
      width: 95%;
      margin: 0 auto; //左右自动对齐
      margin: 10rpx 10rpx;
      border-radius: 20rpx;
      padding: 20rpx;  // padding 设置内边距
    }
  }
 
  .btn {
    width: 90%;
    margin: 20rpx auto;
  }
}

 

效果展示图 

五.订单页面

 dingdan.wxml配置

<!--pages/orders/orders.wxml-->
<view class="order-container container">
  <view class="order-list">
    <view class="order-item" wx:for="{{3}}" wx:key="index">
 
      <!-- 订单 -->
      <view class="order-item-header list-flex">
        <view class="orderno">订单号1008686<text></text></view>
        <view class="order-status"> 已支付</view>
      </view>
      <view class="goods-item list-flex">
        <view class="left">
          <image src="../../assets/images/floor-img.jpg" mode="widthFix" class="img" />
        </view>
 
        <!-- 文字 -->
        <view class="zi">
          <view class="zi1">不变的承诺</view>
          <view class="zi2">不变的承诺</view>
        </view>
 
        <view class="qian">
          <view class="qian1">¥299</view>
          <view class="qian2">x1</view>
        </view>
      </view>
 
      <view class="shifu">
        <view class="abc list-flex">
          <text class="abc1">实付</text>
          <text class="abc2"><text>¥</text>199</text>
        </view>
      </view>
    </view>
  </view>
</view>

dingdan.scss样式配置 

/* pages/order/list/index.wxss */
.order-container {
  background-color: whitesmoke;
 
  .order-item {
    background-color: white;
    padding: 25rpx 30rpx 25rpx; // padding 设置内边距
    margin-top: 12rpx; //上下
 
    .order-item-header {
      margin-bottom: 24rpx;
      align-items: center;
      justify-content: space-between;
    }
 
    .list-flex {
      display: flex;
      background-color: white;
    }
 
    .dingdan {
      color: #333333;
      font-size: 20rpx; // 字体大小
      line-height: 40rpx;
      align-items: center;
      font-weight: normal;
      display: flex;
     
    }
 
    .order-status {
      font-weight: bolder; // 字体加粗
      font-size: 38rpx; // 字体大小
      line-height: 40rpx;
    }
 
    .order-active {
      color: #fa4126;
    }
 
    .goods-item {
      padding: 16rpx 0; // padding 设置内边距
 
      .left {
        width: 200rpx;
        height: 190rpx;
 
        .img {
          border-radius: 20rpx;
          width: 220rpx;
          height: rpx;
        }
      }
 
      .zi {
        position: relative; //相对定位
        top: 20rpx; //上下平移
        flex: 1;
        margin: 0 20px; // margin 设置框外边距
 
        .zi1 {
          color: #333;
          font-size: 30rpx; // 字体大小
 
          line-height: 50rpx;
          font-weight: 400;
        }
 
        .zi2 {
          color: #999999;
          font-size: 28rpx; // 字体大小
          height: 32rpx;
 
 
          margin: 10rpx 0rpx;
        }
      }
 
      .qian {
        .qian1 {
 
          color: #fa4126;
          font-size: 24rpx; // 字体大小
          line-height: 48rpx;
        }
 
        .qian2 {
          order: 4;
          text-align: right;
          font-size: 24rpx; // 字体大小
          color: #999;
          margin: 20rpx 0 0 auto;
        }
      }
    }
 
    .shifu {
      .abc {
        justify-content: flex-end;
        align-items: center;
      }
 
      .abc1 {
        font-size: 28rpx; // 字体大小
        line-height: 40rpx;
        color: #333333;
        margin-right: 4px;
      }
 
      .abc2 {
        color: #fa4126;
        font-weight: bolder; // 字体加粗
        font-size: 35rpx; // 字体大小
      }
    }
 
  }
}

效果展示图

六.通用模块封装

1.消息提示模块封装

封装思路
a:创建⼀个 toast ⽅法对 wx.showToast() ⽅法进⾏封装
b:调⽤该⽅法时,传递对象作为参数
如果没有传递任何参数,设置⼀个空对象 {} 作为默认参数
从对象中包含 title 、 icon 、 duration 、 mask 参数,并给参数设置默认值、
const toast = ({title="数据加载中",icon="none",duration=2000,mask=true} = {}) =>
{
 wx.showToast({
 title,
 icon,
 duration,
 mask
 })
 }
c:在需要显示弹出框的时候调⽤ toast ⽅法,并传⼊相关的参数,有两种参数⽅式:
不传递参数,使⽤默认参值 传⼊部分参数,覆盖默认的参数
调⽤⽅法
a:模块化的⽅式导⼊使⽤
export { toast }
import { toast } from './extendApi'
toast()
toast({ title: '数据加载失败....', mask: true })
b:将封装的模块挂载到 wx 全局对象身上
wx.toast = toast

import './utils/extendApi'

wx.toast()
wx.toast({ title: '数据加载失败....', mask: true })

封装步骤 

a:在utils⽂件夹内新建extendApi.js
b:完成extendApi.js⽂件
 // function toast () {}

 // 在使⽤toast⽅法时,可以传⼊参数,也可以不传⼊参数。
 // 如果需要传⼊参数,要传⼊对象作为参数。
 // const toast = (option = {}) => { }

 // 在形参数、位置通过解构的⽅式获取⽤户传⼊的参数,同时设置默认
 const toast = ({title="数据加载中",icon="none",duration=2000,mask=true} = {}) =>
{
 wx.showToast({
 title,
 icon,
 duration,
 mask
 })
 }

 // 局部暴露toast⽅法
 export { toast }

 // 如果其他.js⽂件,需要使⽤toast⽅法,需要导⼊toast,然后进⾏调⽤才可以。

 // 如果有很多的.js⽂件,都需要调⽤toast⽅法
 // 每次使⽤都需要导⼊toast再调⽤,太麻烦了
 // 可以将toast⽅法挂载到wx全局对象上
 // 全局挂载⽅法
 wx.toast = toast

c:调用步骤 

 // app.js
 // import { toast } from './utils/extendApi'
 // import './utils/extendApi'

 App({
 // ⻚⾯显示⽣命周期函数
 onShow() {
 
 // 局部导⼊
 // 不传参数
 // toast()
 // 传⼊参数,传⼊的参数会覆盖默认的参数。
 // toast({title:'数据加载完毕', icon:'success'})

 // 全局导⼊
 // wx.toast()
 // wx.toast({ title: '数据加载失败....', mask: true })

 }
 })

2.模块对话框封装 

封装思路
a:对 wx.showModal() ⽅法进⾏封装, 封装后的新⽅法叫 modal。
b:调⽤该⽅法时,传递对象作为参数,对象的参数同 wx.showModal() 参数⼀致。
c:封装的 modal ⽅法的内部通过 Promise 返回⽤户执⾏的操作(确定和取消,都通过 resolve 返
回)。
d:在需要显示模态对话框的时候调⽤ modal ⽅法,并传⼊相关的参数,有三种调⽤⽅式:
不传递参数,使⽤默认参数。
传递参数,覆盖默认的参数
调⽤⽅式
新封装的本地存储模块,我们依然希望有两种调⽤的⽅式:
a:模块化的⽅式导⼊使⽤
b:将封装的模块挂载到 wx 全局对象身上
代码实现
// exendApi.js

 // function toast () {}

 // 在调⽤modal⽅法时,可以传递参数,也可以不传递参数。
 // 如果不传递参数,默认值就是空对象。
 // 如果传递参数,参数需要时⼀个对象,对象中的属性需要和wx.showModal参数保持⼀致。
 const modal = (options = {}) => {
 // 在⽅法内部需要通过Promise返回⽤户的操作
 // 如果⽤户点击了确认,需要通过resolve返回true
 // 如果⽤户点击了取消,需要通过resolve返回false

 return new Promise((resolve) => {
 // 默认的参数
 const defaultOpt = {
 title: '提示', // 提示的标题
 content: '您确定执⾏该操作吗?', // 提示的内容
 confirmColor: '#f3514f',
 // 接⼝调⽤结束的回调函数(调⽤成功、失败都会执⾏)
 complete({ confirm, cancel }) {
 confirm && console.log('点击了确定')
 cancel && console.log('点击了取消')
 }
 }

 // 通过object.assgin⽅法将参数进⾏合并
 // 需要使⽤传⼊的参数覆盖默认的参数
 // 为了不影响默认的参数,需要将合并以后的参数赋值给⼀个空对象
 const opts = Object.assign({}, defaultOpt, options)

 wx.showModal({
 // 将合并以后的参数通过展开运算符赋值给wx.showModal对象
 ...opts,
 complete({ confirm, cancel }) {
 // 如果⽤户点击了确定,通过 resolve 抛出 true
 // 如果⽤户点击了取消,通过 resolve 抛出 false
 confirm && resolve(true)
 cancel && resolve(false)
 }
 })
 })
 }

 export { modal }

 wx.modal = modal

 // app.js

 // app.js
 // import { toast } from './utils/extendApi'
 import './utils/extendApi'

 App({
 // ⻚⾯显示⽣命周期函数
 async onShow() {

 // wx.showModal({
 // title: '提示', // 提示的标题
 // content: '您确定执⾏该操作吗?', // 提示的内容
 // confirmColor: '#f3514f',
 // // 接⼝调⽤结束的回调函数(调⽤成功、失败都会执⾏)
 // complete({ confirm, cancel }) {
 // confirm && console.log('点击了确定')
 // cancel && console.log('点击了取消')
 // }
 // })

 // 不传⼊参数
 // const res = await wx.modal()

 // 传⼊参数
 const res = await wx.modal({
 title:'新的提示',
 showCancel:false
 })

 console.log(res);
 
 }

 })

 3.封装本地存储API

实现步骤
在 utils ⽬录下新建 storage.js ⽂件
在该⽂件中,封装对本地数据进⾏ 存储、获取、删除、清除的⽅法
运行代码
1 // utils/storage.js
2
3 /**
4 * @description 存储数据
5 * @param {*} key 本地缓存中指定的 key
6 * @param {*} value 需要缓存的数据
7 */
8 export const setStorage = (key, value) => {
9 try {
10 wx.setStorageSync(key, value)
11 } catch (e) {
12 console.error(`存储指定 ${key} 数据发⽣错误:`, e)
13 }
14 }
15
16 /**
17 * @description 从本地读取对应 key 的数据
18 * @param {*} key
19 */
20 export const getStorage = (key) => {
21 try {
22 const value = wx.getStorageSync(key)
23 if (value) {
24 return value
25 }
26 } catch (e) {
27 console.error(`获取指定 ${key} 数据发⽣错误:`, e)
28 }
29 }
30
31 /**
32 * @description 从本地移除指定 key 数据
33 * @param {*} key
34 */
35 export const removeStorage = (key) => {
36 try {
37 wx.removeStorageSync(key)
38 } catch (err) {
39 console.error(`移除指定 ${key} 数据发⽣错误:`, e)
40 }
41 }
42
43 /**
44 * @description 从本地清空全部的数据
45 */
46 export const clearStorage = () => {
47 try {
48 wx.clearStorageSync()
49 } catch (e) {
50 console.error("清空本地存储时发⽣错误:", e);
51 }
52 }
53

1 // app.js
2
3 import {setStorage,getStorage,removeStorage,clearStorage} from './utils/storage'
4
5 App({
6 // ⻚⾯显示⽣命周期函数
7 async onShow() {
8
9 setStorage('name','tom'),
10 setStorage('age',10)
11
12 const name = getStorage('name')
13 console.log(name);
14
15 removeStorage('name')
16
17 clearStorage()
18
19 }
20
21 })
22

 

七. 网络请求封装

1.请求封装-request⽅法

a:request⽅法封装
1 // utils/request.js
2
3 // 创建 WxRequest 类
4 // 通过类的⽅式来进⾏封装,会让代码更加具有复⽤性
5 // 也可以⽅便添加新的属性和⽅法
6
7 class WxRequest {
8
9 // ⽤于创建和初始化类的属性以及⽅法
10 constructor(){}
11
12 // request实例⽅法接受⼀个对象类型的参数
13 // 属性值和wx.request⽅法调⽤时传递的参数保持⼀致
14 request(options){
15
16 // 需要通过Promise封装wx.requset,处理异步请求
17 return new Promise((resolve,reject) => {
18
19 wx.request({
20 ...options,
21
22 // 当接⼝调⽤成功时会触发 success 回调函数
23 success:(res) => {
24 resolve(res)
25 },
26
27 // 当接⼝调⽤失败时会触发 fail 回调函数
28 fail:(err) => {
29 reject(err)
30 }
31 })
32 })
33 }
34 }
35

b:request⽅法使⽤  

1 <!--pages/test/test.wxml-->
2 <!-- <text>pages/test/test.wxml</text> -->
3
4 <view class="box">
5 <button type="warn" plain size="mini" bindtap="handler">测试发送请求</button>
6 </view>
1 /* pages/test/test.wxss */
2
3 .box {
4 display: flex;
5 height: 200rpx;
6 justify-content: center;
7 align-items: center;
8 }
1 // test.js
2
3 import instance from '../../utils/request'
4
5 Page({
6
7 // 点击按钮触发 handler ⽅法
8 async handler() {
9
10 // 第⼀种调⽤⽅式:通过 then 和 catch 接收返回的值
11 instance
12 .request({
13 url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
14 method: 'GET'
15 })
16 .then((res) => {
17 console.log(res)
18 })
19 .catch((err) => {
20 console.log(err)
21 })
22
23 // 第⼆种调⽤⽅式:通过 await 和 async 接收返回的值
24 // const res = await instance.request({
25 // url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
26 // method: 'GET'
27 // })
28
29 console.log(res)
30 }
31
32 })
33

2.请求封装——设置请求参数

a:思路分析
在发起⽹络请求时,需要配置⼀些请求参数,
其中有⼀些参数我们可以设置为默认参数,例如:请求⽅法、超时时⻓ 等等,因此我们在封装时我们
要定义⼀些默认的参数。
1 // 默认参数对象
2 defaults = {
3 baseURL: '', // 请求基准地址
4 url: '', // 开发者服务器接⼝地址
5 data: null, // 请求参数
6 method: 'GET',// 默认请求⽅法
7 // 请求头
8 header: {
9 'Content-type': 'application/json' // 设置数据的交互格式
10 },
11 timeout: 60000 // ⼩程序默认超时时间是 60000,⼀分钟
12 // 其他参数...
13 }

但是不同的项⽬,请求参数的设置是不同的,我们还需要允许在进⾏实例化的时候,传⼊参数,对默
认的参数进⾏修改。例如:
1 // 对 WxRequest 进⾏实例化
2 const instance = new WxRequest({
3 baseURL: 'https://gmall-prod.atguigu.cn/mall-api', // 请求基准地址
4 timeout: 10000 // 微信⼩程序 timeout 默认值为 60000
5 })
6

 在通过实例,调⽤ request 实例⽅法时也会传⼊相关的请求参数。

1 const res = await instance.request({
2 url: '/index/findBanner',
3 method: 'GET'
4 })
5

从⽽得出结论:请求参数的设置有 三种⽅式
1. 默认参数:在 WxRequest 类中添加 defaults 实例属性来设置默认值
2. 实例化时参数:在对 WxRequest 类进⾏实例化时传⼊相关的参数,需要在 constructor 构造
函数形参进⾏接收
3. 调⽤实例⽅法时传⼊请求参数

3.封装请求快捷⽅法

a:思路分析
⽬前已经完成了 request() 请求⽅法的封装,同时处理了请求参数。
每次发送请求时都使⽤ request() ⽅法即可,但是项⽬中的接⼝地址有很多,不是很简洁。
1 const res = await instance.request({
2 url: '/index/findBanner',
3 method: 'GET'
4 })

所以我们在 request() 基础上封装⼀些快捷⽅法,简化 request() 的调⽤。
需要封装 4 个快捷⽅法,分别是 get 、 delete 、 post 、 put ,他们的调⽤⽅式如下:
1 instance.get('请求地址', '请求参数', '请求配置')
2 instance.delete('请求地址', '请求参数', '请求配置')
3 instance.post('请求地址', '请求参数', '请求配置')
4 instance.put('请求地址', '请求参数', '请求配置')

这 4 个请求⽅法,都是通过实例化的⽅式进⾏调⽤,所以需要 Request 类中暴露出来
get 、 delete 、 post 、 put ⽅法。每个⽅法接收三个参数,分别是:接⼝地址、请求参数以及其他
参数。
这 4 个快捷⽅法,本质上其实还是调⽤ request ⽅法,我们只要在⽅法内部组织好参数,调⽤
request 发送请求即可。

 

1 class WxRequest {
2 
3 // coding...
4
5 + // 封装 GET 实例⽅法
6 + get(url, data = {}, config = {}) {
7 + return this.request(Object.assign({ url, data, method: 'GET' }, config))
8 + }
9
10 + // 封装 POST 实例⽅法
11 + post(url, data = {}, config = {}) {
12 + return this.request(Object.assign({ url, data, method: 'POST' }, config))
13 + }
14
15 + // 封装 PUT 实例⽅法
16 + put(url, data = {}, config = {}) {
17 + return this.request(Object.assign({ url, data, method: 'PUT' }, config))
18 + }
19
20 + // 封装 DELETE 实例⽅法
21 + delete(url, data = {}, config = {}) {
22 + return this.request(Object.assign({ url, data, method: 'DELETE' },
config))
23 + }
24 }
25 
26 // ----------------- 实例化 ----------------------
27
28 // 对 WxRequest 进⾏实例化
29 const instance = new WxRequest({
30 baseURL: 'https://gmall-prod.atguigu.cn/mall-api',
31 timeout: 15000
32 })
33
34 // 将 WxRequest 的实例通过模块化的⽅式暴露出去
35 export default instance
36

运行代码

 

1 utils/request.js
2
3 class WxRequest {
4 
5 // coding...
6
7 + // 封装 GET 实例⽅法
8 + get(url, data = {}, config = {}) {
9 + return this.request(Object.assign({ url, data, method: 'GET' }, config))
10 + }
11
12 + // 封装 POST 实例⽅法
13 + post(url, data = {}, config = {}) {
14 + return this.request(Object.assign({ url, data, method: 'POST' }, config))
15 + }
16
17 + // 封装 PUT 实例⽅法
18 + put(url, data = {}, config = {}) {
19 + return this.request(Object.assign({ url, data, method: 'PUT' }, config))
20 + }
21
22 + // 封装 DELETE 实例⽅法
23 + delete(url, data = {}, config = {}) {
24 + return this.request(Object.assign({ url, data, method: 'DELETE' },
config))
25 + }
26 }
27 
28 // ----------------- 实例化 ----------------------
29
30 // 对 WxRequest 进⾏实例化
31 const instance = new WxRequest({
32 baseURL: 'https://gmall-prod.atguigu.cn/mall-api',
33 timeout: 15000
34 })
35
36 // 将 WxRequest 的实例通过模块化的⽅式暴露出去
37 export default instance
38
1 /pages/test/test.js
2
3 // 导⼊创建的实例
4 import instance from '../../utils/wx-request'
5
6 Page({
7 async handler() {
8 
9 // 第⼀种调⽤⽅式:通过 then 和 catch 接收返回的值
10 // instance
11 // .request({
12 // url: 'https://gmall-prod.atguigu.cn/mall-api/index/findBanner',
13 // method: 'GET'
14 // })
15 // .then((res) => {
16 // console.log(res)
17 // })
18 // .catch((err) => {
19 // console.log(err)
20 // })
21
22 // 第⼆种调⽤⽅式
23 // 通过实例调⽤ request ⽅法发送请求
24 // const res = await instance.request({
25 // url: '/index/findBanner',
26 // method: 'GET'
27 // })
28 // console.log(res)
29
30 // 第三种调⽤⽅式:通过调⽤快捷⽅式接收返回的值
31 const res = await instance.get('/index/findBanner')
32 console.log(res)
33 }
34 })
35

添加参数 

1 //test.js
2
3 const res = await instance.get('/index/findBanner',{test:111},{timeout:20000})
4
5 console.log(res)
1 // request.js
2
3 // 合并请求参数
4 options = { ...this.defaults, ...options }
5
6 +console.log(options);

4.定义请求/响应拦截器

拦截器和响应拦截器:
请求拦截器本质上是在请求之前调⽤的函数,⽤来对请求参数进⾏新增和修改
响应拦截器本质上是在响应之后调⽤的函数,⽤来对响应数据做点什么
拦截器的使⽤⽅式:
1 // 请求拦截器
2 instance.interceptors.request = (config) => {
3 
4 // 在发送请求之前做些什么
5 return config
6 }
7
8 // 响应拦截器
9 instance.interceptors.response = (response) => {
10 
11 // 对响应数据做点什么
12 return response
13 }

通过使⽤⽅式,我们可以得出结论:
可以在 WxRequest 类内部定义 interceptors 实例属性,属性中需要包含 request 以及 response
⽅法
需要注意:在发送请求时,还需要区分是否通过实例调⽤了拦截器:
1. 没有通过实例调⽤拦截器,需要定义默认拦截器,在默认拦截器中,需要将请求参数进⾏返回
2. 通过实例调⽤拦截器,那么实例调⽤的拦截器会覆盖默认的拦截器⽅法,然后将新增或修改的请求
参数进⾏返回
实现拦截器的思路:
1. 在 WxRequest 类内部定义 interceptors 实例属性,属性中需要包含 request 以及 response ⽅
2. 是否通过实例调⽤了拦截器
是:定义默认拦截器
否:实例调⽤的拦截器覆盖默认拦截器
3. 在发送请求之前,调⽤请求拦截器
4. 在服务器响应以后,调⽤响应拦截器
不管成功、失败响应,都需要调⽤响应拦截器
在 WxRequest 类内部定义 interceptors 实例属性,属性中需要包含 request 以及 response ⽅
法。
没有使⽤拦截器,定义默认拦截器,需要将默认的请求参数进⾏返回。
如果使⽤了拦截器,那么使⽤者的拦截器会覆盖默认的拦截器⽅法。

八.商品首页

分析轮播图区域并渲染

a:分析轮播图结构
轮播图区域采⽤组件化⽅式开发,我们在 index ⽬录下新建 banner ⽂件夹,⾥⾯存放轮播图组件。
在 index/index.json ⽂件中导⼊组件,然后将组件当成标签进⾏使⽤。
1 {
2 "usingComponents": {
3 "banner": "./banner/banner"
4 }
5 }

 

1 <!--pages/index/banner/banner.wxml-->
2
3 <!-- 轮播图 -->
4 <view class="swiper-box">
5 <!-- swiper 滑块视图容器 -->
6 <swiper
7 autoplay
8 class="swiper"
9 indicator-active-color="#FF734C"
10 interval="2000"
11 duration="1000"
12 indicator-color="rgba(0, 0, 0, .3)"
13 >
14 <!-- 使⽤ block 标签实现通过数组进⾏列表渲染 -->
15 <block wx:for="{{ bannerList }}" wx:key="index">
16 <!-- swiper-item 单个滑块视图容器 -->
17 <swiper-item class="swiper-item">
18 <!-- 通过 navigator 组件跳转的链接 -->
19 <navigator
20 class="navigator"
21 url="/pages/goods/detail/detail?goodsId=id"
22 >
23 <image class="img" src="{{ item }}"></image>
24 </navigator>
25 </swiper-item>
26 </block>
27 </swiper>
28
29 <!-- 轮播图的⾯板指示点,因为⾯板指示点不⽀持,所以我们只能通过⾃定义结构的⽅式 -->
30 <view class="indicator">
31 <!-- active 类名:当前被激活的⾯板指示点颜⾊ -->
32 <!-- circle 类名:默认的⾯板指示点颜⾊ -->
33 <text
34 wx:for="{{bannerList.length}}"
35 wx:key="id"
36 class="{{ 'active rectangle' }}"
37 ></text>
38 </view>
39 </view>
40

1. swiper 、 swiper-item 、 navigator 、 image 组件实现⻚⾯结构的搭建
2. block 渲染数组,实现列表渲染
3. 使⽤ flex 布局实现了⻚⾯样式的绘制
另外需要注意的是:轮播图⾯板指示点不⽀持⾃定义,所以只能⻚⾯结构的⽅式,实现轮播图的⾯板
指示点功能

 

b:渲染⻚⾯结构

1 // page/index/index.html
2
3 <!-- 轮播图区域 -->
4 <banner bannerList="{{ bannerList }}" />

1 // page/index/banner/banner.wxml
2
3 <!-- 使⽤ block 标签实现通过数组进⾏列表渲染 -->
4 <block wx:for="{{ bannerList }}" wx:key="index">
5 <!-- swiper-item 单个滑块视图容器 -->
6 <swiper-item class="swiper-item">
7 <!-- 通过 navigator 组件跳转的链接 -->
8 <navigator
9 class="navigator"
10 + url="/pages/goods/detail/detail?goodsId={{item.id}}"
11 >
12 + <image class="img" src="{{ item.imageUrl }}"></image>
13 </navigator>
14 </swiper-item>
15 </block>

 

实现轮播图和指示点的联动 

 c:代码实现

1 <!--pages/index/banner/banner.wxml-->
2 <!-- 轮播图 -->
3 <view class="swiper-box">
4 <swiper
5 autoplay
6 class="swiper"
7 indicator-active-color="#FF734C"
8 interval="2000"
9 duration="1000"
10 indicator-color="rgba(0, 0, 0, .3)"
11 + bindchange="getSwiperIndex"
12 >
13 <block wx:for="{{ bannerList }}" wx:key="index">
14 <swiper-item class="swiper-item">
15 <navigator
16 class="navigator"
17 url="/pages/goods/detail/detail?goodsId={{ item.id }}"
18 >
19 <image class="img" src="{{ item.imageUrl }}"></image>
20 </navigator>
21 </swiper-item>
22 </block>
23 </swiper>
24
25 <!-- 轮播图的⾯板指示点,因为⾯板指示点不⽀持,所以我们只能通过⾃定义结构的⽅式 -->
26 <view class="indicator">
27 <!-- active 类名:当前被激活的⾯板指示点颜⾊ -->
28 <!-- rectangle 类名:默认的⾯板指示点颜⾊ -->
29 <text
30 wx:for="{{bannerList.length}}"
31 wx:key="id"
32 + class="{{ index === activeIndex ? 'active rectangle' : 'rectangle' }}"
33 ></text>
34 </view>
35 </view>
36

1 // pages/index/banner/banner.js
2
3 Component({
4 /**
5 * 组件的属性列表
6 */
7 properties: {
8 // 轮播图数据
9 bannerList: {
10 type: Array,
11 value: [
12 '../../../assets/banner/banner-1.jpg',
13 '../../../assets/banner/banner-2.jpg',
14 '../../../assets/banner/banner-3.jpg'
15 ]
16 }
17 },
18
19 /**
20 * 组件的初始数据
21 */
22 data: {
23 + activeIndex:0 // 被激活的轮播图索引,默认是0
24 },
25
26 /**
27 * 组件的⽅法列表
28 */
29 methods: {
30 + // 获取被激活的轮播图索引
31 + getSwiperIndex(event){
32
33 + // console.log(event);
34
35 + const { current } = event.detail
36
37 + this.setData({
38 + activeIndex:current
39 })
40 }
41 }
42 })
43

 

渲染分类导航  

a:渲染导航分类结构
1 <!-- 导航分类 -->
2 <entrance cateList="{{ categoryList }}"/>

1 // pages/index/entrance/entrance.html
2
3 <view class="nav-list">
4 <!-- ⼀级分类导航容器 -->
5 <view
6 + wx:for="{{ cateList }}"
7 wx:key="index"
8 class="nav-item {{ index >= 5 ? 'small' : '' }}"
9 >
10 <!-- 导航链接 -->
11 <navigator
12 class="navigator-nav"
13 + url="/pages/goods/list/list?category1Id={{item.id}}"
14 >
15 + <image class="nav-img" src="{{ item.imageUrl }}" />
16 + <text class="nav-text">{{ item.name }}</text>
17 </navigator>
18 </view>
19 </view>

 

b:导航分类结构样式调整  

1 /* pages/index/entrance/entrance.wxss */
2
3 /* 导航分类样式 */
4 .nav-list {
5 display: flex;
6 align-items: center;
7 flex-wrap: wrap;
8 margin: 20rpx 0rpx;
9 border-radius: 18rpx;
10 padding: 10px 0;
11 background-color: #fff;
12
13 .nav-item {
14 flex: 1;
15 min-width: 20%;
16 max-width: 20%;
17
18 &.small {
19 margin-top: 36rpx;
20
21 + .nav-img {
22 + width: 50rpx !important;
23 + height: 50rpx !important;
24 }
25 }
26 }
27 }

渲染活动区域 

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

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

a:将数据传递给 goods-list 组件
1 // page/index/index.wxml 
2
3 <!-- 商品列表 -->
4 <goods-list title="猜你喜欢" list="{{ guessList }}"></goods-list>
5 <goods-list title="⼈⽓推荐" list="{{ hotList }}"></goods-list>

 b:接收⾸⻚传递的 list 数据

1 // components/goods-list/good-list.js
2
3 Component({
4 // 组件的属性列表
5 properties: {
6 // 列表标题
7 title: {
8 type: String,
9 value: '',
10 },
11
12 // 传递的列表数据
13 list: {
14 type: Array,
15 value: []
16 }
17 }
18
19 // coding...
20 }

c:遍历 goods-item 组件,并将数据传递给 goods-item 

1 // components/goods-list/goods-list.wxml
2
3 <!-- 商品列表组件 -->
4 + <view class="goods_container" wx:if="{{ list.length }}">
5 
6 <!-- 标题 -->
7 + <view class="goods_title">{{title}}</view>
8 
9 <!-- 列表区域 -->
10 <view class="goods_card_list">
11 + <goods-card wx:for="{{ list }}" wx:key="id" goodItem="{{ item }}"></goodscard>
12 </view>
13 
14 <!-- 查看更多 -->
15 <!-- coding -->
16 </view>

d:将数据传递给 goods-item 组件 

1 // components/goods-card/goods-card.js
2
3 Component({
4 
5 // 组件的属性列表
6 properties: {
7 // 每⼀项商品的数据
8 goodItem: {
9 type: Object,
10 value: {}
11 }
12 }
13
14 // coding...
15 }

e:将数据传递给 goods-item 组件 

1 // components/goods-list/goods-item.wxml 
2
3 <!-- 列表分类卡⽚ -->
4 <view class="goods_cart_container">
5 <navigator class="navigator_nav" url="/pages/goods/detail/detail?goodsId=
{{goodItem.id}}">
6
7 <!-- 商品图⽚ -->
8 <image class="good_img" src="{{ goodItem.imageUrl }}" mode="widthFix" />
9
10 <!-- 商品详细信息 -->
11 <view class="goods_item_info">
12 <!-- 商品名称 -->
13 <text class="goods_item_info_name">{{ goodItem.name }}</text>
14 <!-- 商品描述 -->
15 <text class="goods_item_info_promo">{{ goodItem.floralLanguage }}</text>
16 <!-- 商品价格 -->
17 <view class="goods_item_info_bottom">
18 <view class="goods_item_info_price">
19 <text class="text">¥</text>{{ goodItem.price }}
20 </view>
21 <view class="goods_item_info_origin_price">
22 <text class="text">¥</text> {{goodItem.marketPrice}}
23 </view>
24 <!-- 加⼊购物⻋图⽚ -->
25 <view class="goods_item_info_btn">
26 <image class="goods_image" src="/static/images/buybtn.png" mode="" />
27 </view>
28 </view>
29 </view>
30 </navigator>
31 </view>

效果展示图

1.不同的请求方式区别(get、post....)
get请求一般用来请求获取数据
post请求一般作为发送数据到后台,传递数据,创建数据;
get请求刷新浏览器或者回退没有影响
post请求则会重新请求一遍;

2.promise的用法:
promise是什么:Promise 是异步编程的一种解决方案,其实是一个构造函数,自己身上有reject、resolve这几个方法,原型上有then、catch等方法
基本语法
const promise = new Promise((resolve, reject) => {});
我们首先使用Promise构造函数实例化一个新的 promise 对象,并向它传递一个回调函数。回调有两个参数,resolve和reject,它们都是函数。我们所有的异步代码都在该回调中。

如果一切运行成功,承诺将通过调用来实现resolve。如果出现错误,则会调用reject。我们可以将值传递给这两种方法,这些方法将在使用代码中可用。

 3.Object.assign的用法 
 Object.assign(target, ...sources)
 参数: target--->目标对象
       source--->源对象
       返回值:target,即目标对象

4.async await的用法
async用于申明function异步,await用于等待一个异步方法执行完成
async函数用于返回一个 Promise 对象

5.baseUrl的使用
配置了 baseURL,之后请求传入的 url 都会和我们的 baseURL 拼接成完整的绝对地址,除非请求传入的 url 已经是绝对地址。

类(Class):用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
方法:类中定义的函数。

 

async函数:async用于声明一个函数是异步的。这意味着函数总是返回一个promise。如果函数内部返回的是非promise值,那么这个值会被自动包装成一个已解决(resolved)的promise。


await表达式:await只能在async函数内部使用,它等待一个Promise对象状态变为已解决,然后返回解决的值。如果Promise状态变为拒绝(rejected),await会抛出异常。


Promise.resolve:用于将一个值转换为一个已解决(resolved)的Promise对象。如果传入的值是一个Promise对象,那么直接返回这个Promise对象;如果传入的值不是Promise对象,那么返回一个新的已解决的Promise对象,其值为传入的值。
Promise.reject:用于创建一个已拒绝(rejected)的Promise对象。它接受一个参数作为拒绝的原因。
Promise.all:用于将多个Promise对象包装成一个新的Promise对象。当所有传入的Promise对象都变为已解决状态时,新的Promise对象才会变为已解决状态;如果有任何一个传入的Promise对象变为已拒绝状态,新的Promise对象也会变为已拒绝状态。

loading的状态通常与请求开始和结束时绑定。当异步操作(如AJAX请求、获取Web API数据等)开始时,显示loading状态;当操作完成并返回数据时,隐藏loading状态。

请求拦截器用于在请求被发送之前修改请求配置,例如添加认证信息、设置请求头等。
响应拦截器用于在接收到响应数据之后进行处理,可以对响应数据进行转换、错误处理等操作。


200 OK: 请求成功,这是最常见和期望的状态码。
201 Created: 请求已成功,并因此创建了一个新的资源。
204 No Content: 请求成功,但没有返回任何内容,只是告诉客户端操作成功了。
400 Bad Request: 客户端请求有语法错误,不能被服务器理解。
401 Unauthorized: 表示需要用户认证。
403 Forbidden: 服务器理解请求但拒绝执行它。
404 Not Found: 请求的资源无法在服务器上找到。
500 Internal Server Error: 服务器遇到了一个未知的错误。
502 Bad Gateway: 作为网关或代理角色的服务器从上游服务器收到无效响应。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值