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 相关文章推荐
JS提交并解析后台返回的XML的代码
Nov 03 Javascript
用于节点操作的API,颠覆原生操作HTML DOM节点的API
Dec 11 Javascript
jquery刷新页面的实现代码(局部及全页面刷新)
Jul 11 Javascript
打印json对象的内容及JSON.stringify函数应用
Mar 29 Javascript
利用js动态添加删除table行的示例代码
Dec 16 Javascript
自己使用jquery写的一个无缝滚动的插件
Apr 30 Javascript
jQuery实现复选框全选/取消全选/反选及获得选择的值
Jun 12 Javascript
javascript中几个容易混淆的概念总结
Apr 14 Javascript
JavaScript+html5 canvas绘制的圆弧荡秋千效果完整实例
Jan 26 Javascript
轻松掌握JavaScript装饰者模式
Aug 27 Javascript
说说AngularJS中的$parse和$eval的用法
Sep 14 Javascript
js实现简单掷骰子效果
Oct 24 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
php把session写入数据库示例
2014/02/26 PHP
php随机抽奖实例分析
2015/03/04 PHP
yii2 resetful 授权验证详解
2017/05/18 PHP
for 循环性能比较 提高for循环的效率
2009/03/19 Javascript
jQuery插件 tabBox实现代码
2010/02/09 Javascript
使用jQuery的将桌面应用程序引入浏览器
2010/11/19 Javascript
用nodejs写的一个简单项目打包工具
2013/05/11 NodeJs
AngularJS基础 ng-selected 指令简单示例
2016/08/03 Javascript
jQuery模拟下拉框选择对应菜单的内容
2017/03/07 Javascript
vue数据双向绑定原理解析(get &amp; set)
2017/03/08 Javascript
Vue数组更新及过滤排序功能
2017/08/10 Javascript
js实现json数组分组合并操作示例
2019/02/12 Javascript
IntelliJ IDEA编辑器配置vue高亮显示
2019/09/26 Javascript
javascript设计模式 ? 外观模式原理与用法实例分析
2020/04/15 Javascript
[01:01:51]EG vs VG Supermajor小组赛B组 BO3 第二场 6.2
2018/06/03 DOTA
[43:33]EG vs Spirit Supermajor 败者组 BO3 第一场 6.4
2018/06/05 DOTA
[42:56]VGJ.S vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
使用cx_freeze把python打包exe示例
2014/01/24 Python
浅析Python中的join()方法的使用
2015/05/19 Python
Python3使用requests发闪存的方法
2016/05/11 Python
python将ansible配置转为json格式实例代码
2017/05/15 Python
python3人脸识别的两种方法
2019/04/25 Python
Python控制Firefox方法总结
2019/06/03 Python
python 解决flask uwsgi 获取不到全局变量的问题
2019/12/22 Python
Python HTMLTestRunner测试报告view按钮失效解决方案
2020/05/25 Python
python怎么判断模块安装完成
2020/06/19 Python
python各种excel写入方式的速度对比
2020/11/10 Python
浅析Python打包时包含静态文件处理方法
2021/01/15 Python
简单聊聊H5的pushState与replaceState的用法
2018/04/03 HTML / CSS
Bibloo荷兰:女士、男士和儿童的服装、鞋子和配饰
2019/02/25 全球购物
ZINVO手表官网:男士和女士手表
2019/03/10 全球购物
OSPREY LONDON官网:英国本土皮具品牌
2019/05/31 全球购物
学校清明节活动总结
2014/07/04 职场文书
离婚协议书的书写要求
2014/09/17 职场文书
企业党的群众路线教育实践活动学习心得体会
2014/10/31 职场文书
OpenStack虚拟机快照和增量备份实现方法
2022/04/04 Servers