taro 实现购物车逻辑的实例代码


Posted in Javascript onJune 05, 2020

taro 实现购物车逻辑

效果

taro 实现购物车逻辑的实例代码

taro是什么?

Taro 是一套遵循 React 语法规范的 多端开发 解决方案。

  • 现如今市面上端的形态多种多样,Web、React-Native、微信小程序等各种端大行其道,当业务要求同时在不同的端都要求有所表现的时候,针对不同的端去编写多套代码的成本显然非常高,这时候只编写一套代码就能够适配到多端的能力就显得极为需要。
  • 使用 Taro,我们可以只书写一套代码,再通过 Taro 的编译工具,将源代码分别编译出可以在不同端(微信/百度/支付宝/字节跳动/QQ/京东小程序、快应用、H5、React-Native 等)运行的代码。本代码是基于Taro UI 开发的,虽然是基于 taro框架开发的,但购物车的整体逻辑与微信小程序逻辑是基本一样的
  • Taro UI是一款基于 Taro 框架开发的多端 UI 组件库

需要安装taro ui

$ npm install taro-ui

taro官方文档

taroUI 官方文档

cart/index.jsx页面代码
import Taro, { Component } from '@tarojs/taro'
import { View, Checkbox, CheckboxGroup } from '@tarojs/components' 
//用到了taro的三个组件
//想了解可以去查看taro的官方文档
import './index.scss'
import { AtButton, AtInputNumber, AtCard } from 'taro-ui'
import { request, toast } from '../../utils/index'

class Index extends Component {
 constructor(props) {
  super(props)
  this.state = {
   message: '', //购物车为空时显示的信息
   cartdata: [], //购物车的数据列表
   isactive: false, //全选按钮是否选中
   check:false, //单个商品购物车是否被选中
   totalnum:0, //总数量
   totalprice:0, //总价格
   activedata:[] //复选框选中的数据列表
  }

 }
 componentDidShow () {
  //获取购物车数据
  try {
   const token = Taro.getStorageSync('token') //这两个数据是我在登录页面,登录时添加到本地的token和用户id
   const userid = Taro.getStorageSync('userid')
   if (token) { //如果登录了
    const usrename = Taro.getStorageSync('username') //同样登录时添加到本地的用户名
    Taro.setNavigationBarTitle({ //改变导航栏的标题
     title: usrename + '---购物车'
    })
    request({ //这里的request是封装后的方法
     url: '/cart', //接口
     data: { //需要传递的数据
      token,
      userid
     }
    }).then(res => { 
     console.log(res.data)
     const { code } = res.data 
     if (code === '10119') { //后端返回的值 ,判断状态
      toast({ title: '登录已经过期,请从新登录' })
      Taro.navigateTo({  //跳转到登录页
       url: '/pages/login/index'
      })
     } else if (code === '10012') { 
      this.setState({
       message: '购物车空空如也'
      })
     } else {
     //因为taro是基于react的,在react中,状态不能直接改变,要用this.setState
      this.setState({ //登录成功,购物车有数据时,将购物车的列表数据添加到购物车数据中 
       cartdata: res.data.data
      })
     }
    })
   } else { //如果没登录
    toast({ title: '请登录' })
    Taro.navigateTo({ //跳转到登录页面
     url: '/pages/login/index'
    })
   }

  } catch (e) {

  }
 }
 componentDidUpdate(){
  //计算总数量,总价格
  let num=0;
  let price=0;
  if(this.state.activedata.length!=0){ //如果选中的数组长度不为0时,就是有商品被选中了
   this.state.activedata.map((item)=>{ //map遍历数组
    num+= +item.num  //将数量相加 + 号为一元运算符,将字符串类型转换为数值类型
    price+=item.num*item.price  //求价格
   }) 
   this.setState({ //设置值
    totalnum:num,
    totalprice:price
   })
  }else{ //如果没有商品被选中
   this.setState({
    totalnum:0,
    totalprice:0
   })
  }
  
 }
 render() {
  return ( //结构开始
   <View>{
    this.state.message.length === 0 ? null : //如果 message不为空的话,就代表着购物车没有数据,所以显示购物车空空如也,去选购,如果为空,代表着购物车有数据,不显示
     <View onClick={() => { //点击事件 去主页选购商品
      Taro.switchTab({
       url: '/pages/home/index'
      })
     }}> {this.state.message}去选购</View>
   }
    <Checkbox checked={this.state.isactive} onClick={()=>{ //全选按钮 check代表着按钮是否选中 因为taro中的checkbox的onchange方法,不支持小程序,所以没办法,只能用 onClick方法
     let active=!this.state.isactive   //实现点击选中状态取反
     this.setState({  
      isactive:active
     })
     if(active===true){ //如果全选,就代表着 购物车的所有商品都被选中,所以,将购物车列表数据全给选中的数组,将单个商品的状态全部设为选中
      this.setState({
       check:true,
       activedata:this.state.cartdata
      })
     }else{//否则,选中商品数组为空,将单个商品的状态全部设为未选中
      this.setState({
       check:false,
       activedata:[]
      })
     }
    }}>全选</Checkbox>

    <CheckboxGroup  onChange={(evt)=>{ //复选框组,<CheckboxGroup/>中选中项发生改变是触发 change 事件,detail = value:[选中的 Checkbox 的 value 的数组]
     const {detail:{value}}=evt 
     if(value.length===this.state.cartdata.length){ //选中的数组的长度如果等于购物车列表的长度是全选
      this.setState({  
       isactive:true,  //全选按钮被选中
       activedata:this.state.cartdata  //选中商品数组为购物车的列表数组
      })
     }else{ //否则未全选
      var i;
      var data=[];
      for ( i in value){  //因为value数组里的值为选中的checkbox的value的值,我设置的为cartid
       data.push(...(this.state.cartdata.filter(item=>{ //过滤下购物车的列表数据,将cartid相等的对象取出来,放进data数组中,...是展开运算符,加他是因为在控制台打印的时候发现,每个对象外面都加了一个【】,没办法,这里应该是有简单的写法的,但因为当时累了,也没有细想,就只能写成这样了,
        return item.cartid==value[i]
       })))
      }
      console.log(data,this.state.cartdata)
      this.setState({
       isactive:false,//全选按钮未被选中
       activedata:data //设置选中商品的数组
       //至此,计算总数量,总价格、全选、单选的逻辑就全完成了,至于为什么写成这样,是因为taro是基于react的标准的,没有计算属性,没有双向绑定
      })
     }
    }}>
     {
      this.state.cartdata.map((item, index) => //循环显示购物车数据
       <AtCard
        title={item.proname}
        thumb={item.proimg}
        extra={'$'+item.price}
        key={item.proid}

       >
        <View><Checkbox value={item.cartid} checked={this.state.check}></Checkbox> 
        {/* 每个商品前的复选框 */}
         <AtInputNumber //数量加减
          min={0}
          max={10}
          step={1}
          value={item.num} //之间的值
          onChange={this.change.bind(this, item,index)} //onchange输入框值改变时触发的事件,开发者需要通过 onChange 事件来更新 value 值变化,onChange 函数必填
         />
         <AtButton type='primary' size='small' onClick={this.del.bind(this,item)}>删除</AtButton> 
         {/* 删除按钮 */}
        </View>

       </AtCard>
      )
     }
    </CheckboxGroup>
    <View>总数量:{this.state.totalnum}</View>
    <View>总价格:{this.state.totalprice}</View>
   </View>
  )
 }
 del(item){ //删除方法
 //item代表着商品的数据 
  try{
   const token = Taro.getStorageSync('token')
   if(token){ //如果有token值
    request({ //数据请求   删除接口
     url: '/cart/delete',
     data: {
      token,
      cartid: item.cartid
     }
    }).then(res => {
     const { code } = res.data
     if (code === '10119') { //后端接口 返回值
      toast({ title: '登录状态过期,请重新登录' })
      Taro.navigateTo({  //跳转到登录页面 
       url: '/pages/login/index'
      })
     }else{ 
       toast({title:'删除成功!'}) //显示提示框 封装的一个方法 其实到这步,商品就已经删除了,但页面还没有发生变化,所以我们要处理下页面
       let id=item.cartid    
       let data1=this.state.cartdata.filter(item=>{ //过滤下不等于被删除的商品id,将未删除的商品,放到data1中
        return item.cartid!=id
       })
       let data2=this.state.activedata.filter(item=>{ //在选中情况下
        return item.cartid!=id
       })
       this.setState({ //设置下购物车列表数据 
        cartdata:data1,
        activedata:data2
       })
     }
    })
   }else{ //如果没有token值
    toast({ title: '请登录' }) 
    Taro.navigateTo({ //跳转到登录页面
     url: '/pages/login/index'
    })
   }
  }catch(e){
    
  }
 }
 change(item,index,evt) {
  //数量改变
  console.log(evt) 
  //item代表着商品的数据 
  //index,为当前改变的是那个商品的值, 
  //evt为改变后的数值
  try {
   const token = Taro.getStorageSync('token') 
   if (token) { //如果有token值
    if (evt === '0') { //数量为0 我设置的为删除商品,与上面的删除一致,这里我就不再解释了
     request({
      url: '/cart/delete',
      data: {
       token,
       cartid: item.cartid
      }
     }).then(res => {
      const { code } = res.data
      if (code === '10119') {
       toast({ title: '登录状态过期,请重新登录' })
       Taro.navigateTo({
        url: '/pages/login/index'
       })
      }else{
        toast({title:'删除成功!'})
        let id=item.cartid
        let data1=this.state.cartdata.filter(item=>{
         return item.cartid!=id
        })
        let data2=this.state.activedata.filter(item=>{ //在选中情况下
        return item.cartid!=id
       })
        this.setState({
         cartdata:data1,
         activedata:data2
        })

      }
     })
    }else{ //改变的值不为0 ,
     request({
      url: '/cart/update', //更新接口 
      data: {
       token,
       cartid: item.cartid,
       num:evt  //将改变的值直接付给num
      }
     }).then(res => {
      const { code } = res.data
      if (code === '10119') {  //后端验证
       toast({ title: '登录状态过期,请重新登录' })
       Taro.navigateTo({ //跳转到登录页
        url: '/pages/login/index'
       })
      }else{
        toast({title:'更新成功!'})
        item.num=evt //改变下数量
       // var newitem=item
       // var data=this.state.cartdata.map(item=>{
       //  return item.cartid===newitem.cartid ?newitem :item
       // })
       var data=this.state.cartdata //将购物车里边数据赋给data ,因为在react中,状态不能直接改变
       data[index]=item // 将新的对象赋给数组的第index对象
       this.setState({ //设置下
        cartdata:data
       })
      }
     })
    }
   } else {//如果没有token值
    toast({ title: '请登录' })
    Taro.navigateTo({
     url: '/pages/login/index'
    })
   }

  } catch (e) {

  }

 }
}

export default Index
cart/index.scss页面代码
@import "~taro-ui/dist/style/components/card.scss";
@import "~taro-ui/dist/style/components/button.scss";
@import "~taro-ui/dist/style/components/loading.scss";
@import "~taro-ui/dist/style/components/icon.scss";
@import "~taro-ui/dist/style/components/input-number.scss";
utils/index.js代码
const publicurl ='',//接口就不放上去了,因为也不是我的,这里就放接口前的公共网址
import Taro from '@tarojs/taro'
export function request(options){
 const {url,data,method}=options
 wx.showLoading({ //显示loading框
  title: '加载中',
 })
 return new Promise((resolve,reject)=>{
  Taro.request({ //数据请求 与小程序类似
   url: publicurl+url,
   data:data || {},
   method:method || 'GET',
   success(res){ 
    //成功
    resolve(res)
   },
   fail(err){
    //失败
    reject(err)
   },
   complete(){
    // complete 接口调用结束的回调函数
    wx.hideLoading(); //隐藏loading框
   }
  })
 })
}

export function toast(options){
  const {title,icon, duration}=options
  Taro.showToast({ 
   title,
   icon: icon || 'none',
   duration:duration || 1000
  })
}

总结

到此这篇关于taro 实现购物车逻辑的实例代码的文章就介绍到这了,更多相关taro 购物车逻辑内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
javascript真的不难-回顾一下基础知识
Jan 15 Javascript
JS 屏蔽键盘不可用与鼠标右键不可用的方法
Nov 18 Javascript
js取float型小数点后两位数的方法
Jan 18 Javascript
js验证上传图片的方法
May 12 Javascript
无需 Flash 使用 jQuery 复制文字到剪贴板
Apr 26 Javascript
Jquery对新插入的节点 绑定Click事件失效的解决方法
Jun 02 Javascript
jquery ajax结合thinkphp的getjson实现跨域的方法
Jun 06 Javascript
JavaScript实现按键精灵的原理分析
Feb 21 Javascript
JavaScript屏蔽Backspace键的实现代码
Nov 02 Javascript
微信小程序 wepy框架与iview-weapp的用法详解
Apr 10 Javascript
JQuery属性操作与循环用法示例
May 15 jQuery
JavaScript array常用方法代码实例详解
Sep 02 Javascript
Node.js API详解之 V8模块用法实例分析
Jun 05 #Javascript
Vue CLI4 Vue.config.js标准配置(最全注释)
Jun 05 #Javascript
使用Taro实现小程序商城的购物车功能模块的实例代码
Jun 05 #Javascript
Vue路由的模块自动化与统一加载实现
Jun 05 #Javascript
Jquery滑动门/tab切换实现方法完整示例
Jun 05 #jQuery
详解JS函数防抖
Jun 05 #Javascript
Vuex的各个模块封装的实现
Jun 05 #Javascript
You might like
destoon会员注册提示“数据校验失败(2)”解决方法
2014/06/21 PHP
如何使用php脚本给html中引用的js和css路径打上版本号
2015/11/18 PHP
jquery checkbox全选、取消全选实现代码
2010/03/05 Javascript
jquery实现对联广告的方法
2015/02/05 Javascript
chrome调试javascript详解
2015/10/21 Javascript
JS实现简单的二维矩阵乘积运算
2016/01/26 Javascript
基于jQuery实现select下拉选择可输入附源码下载
2016/02/03 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
Javascript 函数的四种调用模式
2016/11/05 Javascript
常用的js方法合集
2017/03/10 Javascript
Angular4学习教程之DOM属性绑定详解
2018/01/04 Javascript
React+Webpack快速上手指南(小结)
2018/08/15 Javascript
详解小程序中h5页面onShow实现及跨页面通信方案
2019/05/30 Javascript
js实现的格式化数字和金额功能简单示例
2019/07/30 Javascript
Vue+Vuex实现自动登录的知识点详解
2020/03/04 Javascript
基于aotu.js实现微信自动添加通讯录中的联系人功能
2020/05/28 Javascript
Python检测网络延迟的代码
2018/05/15 Python
python opencv实现运动检测
2018/07/10 Python
python使用Matplotlib画条形图
2020/03/25 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
python实现把二维列表变为一维列表的方法分析
2019/10/08 Python
python/golang 删除链表中的元素
2020/09/14 Python
Html5 webRTC简单实现视频调用的示例代码
2020/09/23 HTML / CSS
美国在线工具商店:Acme Tools
2018/06/26 全球购物
求职者简历中的自我评价
2013/10/20 职场文书
骨干教师培训制度
2014/01/13 职场文书
区优秀教师事迹材料
2014/02/10 职场文书
志愿者服务感言
2014/02/27 职场文书
竞选班长自荐书范文
2014/03/09 职场文书
古汉语文学求职信范文
2014/03/16 职场文书
人力资源管理专业自荐书
2014/07/07 职场文书
给女朋友道歉的话大全
2015/01/20 职场文书
2015年妇幼保健工作总结
2015/05/19 职场文书
培训感想范文
2015/08/07 职场文书
Mysql中@和@@符号的详细使用指南
2022/06/05 MySQL