12小程序购物车

导读:本篇文章讲解 12小程序购物车,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

数据库连表查询

json-server 连接数据中的表
localhost:3000/carts?_expand=good --> 当前购物车商品的详情信息

命名要有统一性:
商品信息数据名:goods
购物车数据id:goodId
购物车接口:localhost:3000/carts?_expand=good

shopCar.wxml


<!-- 引入wxs文件 -->
<wxs src="./shopCar.wxs" module="shopCarModule" />

<!-- ---------------------------------购物车空空如也-------------------------- -->
<view wx:if="{{ !carList.length }}" style="text-align: center; ">
  购物车空空如也
</view>
<!-- ---------------------------------购物车不为空------------------------------ -->

<view wx:else>
    <!-- 全选/全不选 -->
    <checkbox-group bindchange="handleSelectAll">
      <!--  -->
      <checkbox value="随便写一个value" checked="{{ shopCarModule.checked(carList) }}"></checkbox>全选
    </checkbox-group> 

  <!-- 购物车商品列表 -->
  <!-- bindlongtap 按压屏幕一段时间 -->
  <view wx:for="{{ carList }}" wx:key="index" class="shopcar" 
    bindlongtap="handelModel" data-id="{{ item.id }}"
  >
    <!-- 复选框,check-group 是多项选择器,内部有多个checkbox组成  -->
    <!-- 方法一:
      <checkbox-group bindchange="handleBoxChange">
        <checkbox value="{{ item.id }}"></checkbox>
      </checkbox-group> 
    -->
    <!-- 方法二: -->
    <checkbox 
      bindtap="handleBoxChange" 
      data-id="{{ item.id }}"
      checked="{{ item.checked }}"
    ></checkbox>

    <!-- 商品图片 -->
    <image src="{{ 'http://localhost:3000' + item.good.poster }}"></image>
    <view>
      <!-- 商品名称 -->
      <view>{{ item.good.name }}</view>
      <!-- 商品价格 -->
      <view style="color: red;">{{ '¥' + item.good.price }}</view>
      <!-- 加减按钮 -->
      <view class="add-reduce">
        <text bindtap="handleReduce" data-id="{{item.id}}">-</text>
        <input value="{{ item.number }}" disabled></input>
        <text bindtap="handleAdd" data-id="{{item.id}}">+</text>
      </view>
    </view>
  </view>

  <!-- 总金额 -->
  <view>
  <!-- 小程序不支持函数调用方法:total(),要用小程序自带语法.wxs(jsx语法) -->
    总金额:{{ shopCarModule.total(carList) }}
  </view>

  <button bindtap="handlePay">支付</button>
</view>


shopCar.js

Page({
  data: {
    carList: []
  },

  onShow: function () { // 每次页面显示再走一遍onShow,跳转页面回到该页面也再走一遍
      // Ajax
      wx.request({
        // json-server提供的特殊功能 _expand
        // 连表查询(在后端做),前端只要拿到接口就行
        url: `http://localhost:3000/carts?_expand=good&username=${wx.getStorageSync('users').nickName}`,
        success: (res) => {
          console.log(res.data)
          this.setData({
            carList: res.data
          })
        }
      })
  },

  // 减
  handleReduce (e) {
    // tmpId 当前商品的id
    let tmpId = e.currentTarget.dataset.id
    // tmpObj 想要更新成的结构
    let tmpObj = null
    let newList = this.data.carList.map(item => {
      if (item.id === tmpId) {
        tmpObj = {
          ...item,
          number: item.number - 1 === 0 ? 1 : (item.number-1)
        }
        return tmpObj
      }
      return item
    })
    this.setData({
      carList: newList
    }),
    // 存到数据库中
    this.updateCart(tmpObj)
  },

  // 加
  handleAdd (e) {
    // tmpId 当前商品的id
    let tmpId = e.currentTarget.dataset.id
    // tmpObj 想要更新成的结构
    let tmpObj = null
    let newList = this.data.carList.map(item => {
      if (item.id === tmpId) {
        tmpObj = {
          ...item,
          number: item.number + 1
        }
        return tmpObj
      }
      return item
    })
    this.setData({
      carList: newList
    }),
    // 存到数据库中
    this.updateCart(tmpObj)
  },

  // 同步数据库操作
  updateCart (cartobj) {
    // 显示loading
    wx.showLoading({
      title: '更新中...',
    })
    // cartObj的对象结构
    let { goodId, number, username, checked } = cartobj
    wx.request({
      url: `http://localhost:3000/carts/${cartobj.id}`,
      method: 'put',
      data: {
        goodId,
        number,
        username,
        checked
      },
      success: () => {
        // 隐藏loading框
        wx.hideLoading()
      }
    })
  },

  // 选中和未选中
  handleBoxChange (e) {
    // 临时变量
    let tmpId = e.currentTarget.dataset.id
    let newList = [...this.data.carList]
    newList.forEach(item => {
      if (item.id === tmpId) {
        // 取反操作
        item.checked = !item.checked
        // 同步数据库
        this.updateCart(item)
      }
    })
    // 更新视图
    this.setData({
      carList: newList
    })
  },

  // 长按
  handelModel (e) {
    wx.showModal({
      title: '提示',
      content: '你确认要删除吗',
      success: (res) => {
        if (res.confirm) {
          this.handleDel(e.currentTarget.dataset.id)
        } else if (res.cancel) {
          console.log('用户点击取消')
        }
      }
    })
  },

  // 删除
  handleDel (id) {
    // 更新视图
    this.setData({
      carList: this.data.carList.filter(item => item.id !== id)
    })
    // 操作数据库
    wx.request({
      url: `http://localhost:3000/carts/${id}`,
      method: 'delete',
      success: (res) => {
        wx.showToast({
          title: '删除成功',
          icon: 'success',
          duration: 2000
        })
      }
    })
  },

  // 全选
  handleSelectAll (e) {
    if (e.detail.value.length === 0) { // 全不选
      // 更新视图
      this.setData({
          carList: this.data.carList.map(item => ({
            ...item,
            checked: false
          }))
      })
      // 同步数据库(json-server中没有好的方法可以一次性put修改多个值,只能写一个遍历,遍历每一个id进行更新)
      // 真实工作中使用put进行更新
    }else { // 全选
      // 更新视图
      this.setData({
          carList: this.data.carList.map(item => ({
            ...item,
            checked: true
          }))
      })
      // 同步数据库
    }
  },

  // 支付
  handlePay () {
    /* 支付流程:(需要微信认证)
      前端带参数向后端发起Ajax请求,后端创建订单,此时订单是未支付状态,
      后端带参数向微信发起请求,微信服务器创建订单,返回prePayId到我们自己的后端,
      我们自己的后端再返回prepayId、签名、时间戳、随机字符串
    */ 
    wx.requestPayment({
      timeStamp: '',
      nonceStr: '',
      package: '',
      signType: 'MD5',
      paySign: '',
      success (res) { },
      fail (res) { }
    })
  }

})

shopCar.wxss

.shopcar {
  display: flex;
}
/* 商品图片 */
.shopcar image {
  width: 200rpx;
  height: 200rpx;
}
/* 加减数量 */
.add-reduce {
  display: flex;
}

.add-reduce input {
  width: 70rpx;
  text-align: center;
}

shopCar.wxs

// wxs 不支持ES6

// 计算总金额
var total = function (carList) {
  var sum = 0
  carList.forEach(function (item) {
    if (item.checked) {
      sum+= item.good.price * item.number
    }
  })
  return sum
}

// 全选/不全选/全不选
function checked (carList) {
  // 判断每个商品的checked是否都是true,如果都是true,就返回true
  // every()  ES5遍历的方法,只要有一个不满足就返回false,所有都满足才返回true
  // some()  只要有一个满足,就返回true,所有的都不满足,就返回false
  if (carList.length === 0) { // 如果购物车没有商品,全选按钮就不勾选
    return false
  }
  var isChecked = carList.every(function (item) {
    // 只要回调函数里有一个返回的是false,就返回false
    return item.checked
  })
  return isChecked
}

// commonJS规范导出
module.exports = { 
  total: total,
  checked: checked 
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/4554.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!