小程序业购物车务逻辑

uni-app & taro 购物车业务逻辑

一、 taro 购物车业务逻辑

1、页面初始渲染业务逻辑

1、发送异步请求 —>判断 返回数据 -->如果未登录,则跳回登录页面 -->若果登陆了判断购物车是否有数据–> 没有数据显示购物车,点击跳转进入商品列表页

componentDidShow () { //在微信小程序中这一生命周期方法对应 onShow
    try {
      // 本地判断是否登陆
      let userid = Taro.getStorageSync('userid')
      let token = Taro.getStorageSync('token')
      if ( userid && token) {
        request({
          url: '/cart',
          data: {
            userid,
            token
          }
        }).then( res => {
          console.log(res.data.code)
          if (res.data.code === '10119') {
            Taro.showToast({
              title: '还未登陆,请先登陆',
              icon: 'none'
            })
            Taro.navigateTo({
              url: '/pages/login/index'
            })
          } else if (res.data.code === '10112') {
            Taro.showToast({
              title: '购物车空空如也,请加购',
              icon: 'none'
            })
            this.setState({
              isTrue: true
            })
          } else {
            res.data.data.map( item => {
              item.flag = true
            })
            this.setState({
              isTrue: false,
              cartlist: res.data.data
            }, () => {
              this.count() // 用来计算总价和总数
            })
            
          }
        })
      } else {
        Taro.showToast({
          title: '还未登陆,请先登陆',
          icon: 'none'
        })
        Taro.navigateTo({
          url: '/pages/login/index'
        })
      }
    } catch (error) {
      
    }
  }

2、异步请求(加、减、删)

/**
 index number  点击时是数据的下标
 item   object    点击时数据下标对应的内容
 status  string    点击的类型 (加、减、删)
*/
// 异步请求 同步数据 库
  numberCompute(index,item,status ){
    let token = Taro.getStorageSync('token')
    let url = null
    let num = null
    if(status==="reduce" || status === "add"){
      url = "/cart/update"
      status==="reduce" ? num = item.num - 1 :num = item.num + 1
    }
    else url = "/cart/delete"
    request({
      url,
      data :{token,cartid: item.cartid, num  },
    }).then(res => {
      if (res.code === '10019') {
        toast({title:'请先登录'})
        Taro.navigateTo({
          url: '/pages/login/index'
        })
      } else {
        toast({title:'修改数量成功'})
        let tempArr = this.state.cartlist
        if(status==="add"){
          tempArr[index].num += 1 
        }else if(status==="reduce")   {
          tempArr[index].num -= 1
        }else {
          tempArr.splice(index,1)
        }
        this.setState({ cartlist: tempArr })
       // 删除当前的数据   this.setState({})
        this.state.cartlist.length === 0 ? this.setState({ flag : true}) : this.setState({ flag : false})  
      //计算总价格
      this.allNumberPrice()
      }
    })
  }

3 、点击触发函数


// 减
reduce(item,ind){
  console.log("reduce")
  let status = "reduce"
  let num = item.num;
  if(num>1) {
    this.numberCompute(ind,item,status)
  }
  
}
// 加
add(item,ind){
  console.log("add")
  let status = "add"
  this.numberCompute(ind,item,status)
}
// 删
del(item, index){
  let status = "del"
  this.numberCompute(index, item,status) 
}

4、点击选中复选框

给cartlist 中的每条数据添加 一个复选框选中状态

/**
*cartlist   列表数据
* status   全选状态
*/
 // 遍历数据  添加cheakbox 
			filterData(cartlist,status = false) {
             cartlist.map((item,index)=>{
          return item.cheacked = status
        })

计算总数量,和总价格 (每次加、减 、删、点击全选&反选、单击复选框时调用)

// 计算总数量 和 总价格
  allNumberPrice(value){
    let numer = 0;
    let price = 0;
    let count= 0;
    this.state.cartlist.forEach((item,index)=>{
      if(item.cheacked){
        count ++
        numer += item.num
        price += item.price * item.num
      }
    })
    this.setState({
      numbertatol:numer,
      pricetatol:price
    })
    count === this.state.cartlist.length ?this.setState({checked : true}) : this.setState({checked : false})
  }

点击全选& 全不选

// 点击全选 和全部选
   		allChoseFn(){
       console.log("点击全选")
       this.setState({
         checked:!this.state.checked,
       })
       let status = !this.state.checked
       this.filterData(this.state.cartlist, status)
       //计算总价格
   			this.allNumberPrice()
   		}
   		// 点击选中改变 总数量和总价
     choseFn (index) {
       console.log("点击单个复选框")
       let tempArr =  this.state.cartlist
       tempArr[index].cheacked = !tempArr[index].cheacked 
       this.setState({cartlist:tempArr})
       this.allNumberPrice()
     }

完整 代码

import Taro, { Component } from '@tarojs/taro'
// 为什呢 View 要单独引入,react 说明 组件的首字母一定要大写,小写被当做html标签
import { View 
,Image,Text,Checkbox,Navigator,CheckboxGroup
} from '@tarojs/components'

import { AtSwipeAction ,AtInput,AtButto} from "taro-ui"

import {request,toast} from '../../utils/request'
import "./index.scss"
class Index extends Component {
constructor (props) {
  super(props)
  this.state = {
    checked:false,
    flag:true,
    cartlist:[],
    numbertatol: 0,
    pricetatol : 0
  }
}
componentDidShow(){
  this.setState({checked:false})
  console.log("diaoyongle")
  this.getCartList()
}
getCartList(){
  try{
    let userid = Taro.getStorageSync('userid')
    let token = Taro.getStorageSync('token')
    if(userid && token){
      request({
        url: '/cart',
        data: {
          userid, token
        }
      }).then(res=>{
        const { code } = res.data
        if (code === '10019') {
          toast({title:'请先登录'})
          Taro.navigateTo({
            url: '/pages/login/index'
          })
        } else if (code === '10012') {
          toast({title:'请先选购商品'})
          this.setState({ flag :true })
        } else {
          toast({title:'购物车列表获取成功'})
          

          this.setState({ flag :false , cartlist : res.data.data })
          this.filterData(res.data.data)
        } 
      })
    }else {
      toast({title:'请先登录'})
          Taro.navigateTo({
            url: '/pages/login/index'
          })
        }
  }catch(e){
    console.log(e)
  }
}

// 减
reduce(item,ind){
  console.log("reduce")
  let status = "reduce"
  let num = item.num;
  if(num>1) {
    this.numberCompute(ind,item,status)
  }
  
}
// 加
add(item,ind){
  console.log("add")
  let status = "add"
  this.numberCompute(ind,item,status)
}
// 删
del(item, index){
  let status = "del"
  this.numberCompute(index, item,status) 
}
// 异步请求 同步数据 库
numberCompute(index,item,status ){
  let token = Taro.getStorageSync('token')
  let url = null
  let num = null
  if(status==="reduce" || status === "add"){
    url = "/cart/update"
    status==="reduce" ? num = item.num - 1 :num = item.num + 1
  }
  else url = "/cart/delete"
  request({
    url,
    data :{token,cartid: item.cartid, num  },
  }).then(res => {
    if (res.code === '10019') {
      toast({title:'请先登录'})
      Taro.navigateTo({
        url: '/pages/login/index'
      })
    } else {
      toast({title:'修改数量成功'})
      let tempArr = this.state.cartlist
      if(status==="add"){
        tempArr[index].num += 1 
      }else if(status==="reduce")   {
        tempArr[index].num -= 1
      }else {
        tempArr.splice(index,1)
      }
      this.setState({ cartlist: tempArr })
     // 删除当前的数据   this.setState({})
      this.state.cartlist.length === 0 ? this.setState({ flag : true}) : this.setState({ flag : false})  
    //计算总价格
    this.allNumberPrice()
    }
  })
}

// 计算总数量 和 总价格
allNumberPrice(value){
  let numer = 0;
  let price = 0;
  let count= 0;
  this.state.cartlist.forEach((item,index)=>{
    if(item.cheacked){
      count ++
      numer += item.num
      price += item.price * item.num
    }
  })
  this.setState({
    numbertatol:numer,
    pricetatol:price
  })
  count === this.state.cartlist.length ?this.setState({checked : true}) : this.setState({checked : false})
}
// // 点击全选 和全部选
  		allChoseFn(){
      console.log("点击全选")
      this.setState({
        checked:!this.state.checked,
      })
      let status = !this.state.checked
      this.filterData(this.state.cartlist, status)
      //计算总价格
  			this.allNumberPrice()
  		}
  		// 点击选中改变 总数量和总价
    choseFn (index) {
      console.log("点击单个复选框")
      let tempArr =  this.state.cartlist
      tempArr[index].cheacked = !tempArr[index].cheacked 
      this.setState({cartlist:tempArr})
      this.allNumberPrice()
    }
    // 遍历数据  添加cheakbox 
  		filterData(cartlist,status = false) {
      cartlist.map((item,index)=>{
        return item.cheacked = status
      })
      
    }
render () {
  let container = null
  if(!this.state.flag){
    container = this.state.cartlist.map((item,index)=>{
        return (<AtSwipeAction options={[
              {
                text: '删除',
                style: {
                  backgroundColor: '#FF4949'
                }
              }
            ]} onClick={(event)=>{
              let status = "del"
              if(event.text==="删除") this.numberCompute(index, item, status = "del") 
            }}>
          <View className='normal'>
            <CheckboxGroup  onChange={this.choseFn.bind(this,index)}>

          <Checkbox checked={item.cheacked} color="#ff0000" style="transform:scale(0.7)" />
            </CheckboxGroup>
            <View><Image src={item.proimg} className="imageClass"></Image></View>
            <View className="text" >
              <View className="title"> {item.proname}</View>
              <View className="price">{item.price}</View>
            </View>
            <View className="numberClass">
              <Text className="number"> X{item.num} </Text>
            </View>
            <View className="caoZuoClass">
            <Text  onClick={this.reduce.bind(this,item,index)}>-</Text>
            <AtInput
            size="small"
              name='value'
              type='text'
              value={item.num}
            />
            <Text  onClick={this.add.bind(this,item,index)}>+</Text>
            </View>
          </View>
        </AtSwipeAction>)
    })
  }
  return !this.state.flag ? (<View>
    <CheckboxGroup onChange={this.allChoseFn.bind(this)}>
         <Checkbox checked={this.state.checked}/>全选
    </CheckboxGroup>
        {container}
        <View class="chose">
              <Text>总数量 :{this.state.numbertatol} </Text>
              <Text>总价格 :¥{this.state.pricetatol} </Text>
            </View>
      </View>) :(<View  class="header">
    购物车空空如也,请 <Text className="navTion" 
    onClick={()=>{
      Taro.switchTab({
         url:'/pages/home/index'
      })
    }}
     >选购商品</Text>
  	</View>)
  
}
}

export default Index

index.scss 样式

@import "~taro-ui/dist/style/components/swipe-action.scss";
@import "~taro-ui/dist/style/components/button.scss";
@import "~taro-ui/dist/style/components/loading.scss";
@import "~taro-ui/dist/style/components/input.scss";
@import "~taro-ui/dist/style/components/icon.scss";
@import "~taro-ui/dist/style/components/checkbox.scss";
@import "~taro-ui/dist/style/components/icon.scss";
.taro-img__mode-scaletofill{
        border: 1px solid #ccc;
        height: 90px;
        width: 90px;
        margin: 5px;
        box-sizing: border-box
}
.taro-img{
    height: 100px;
    width: 100%;
    display: flex;
    border-bottom:1rpx solid #ccc;
}
.normal{
    display: flex
}
.text{
	width: 100px;
    padding: 3px 5px;
    .title{
        font-size: 20px;
        width:150px;
        white-space: nowrap;
        text-overflow: ellipsis;
        overflow: hidden;
    }
    .price{
        font-size: 20px;
        
    }
    
}
.numberClass{
    flex: 1;
    font-size: 20px;
     display: flex;
     align-items: center;
     .number{
         width: 100%;
         text-align: center;
         color: red;
     }
}
.caoZuoClass{
    width: 150px;
    align-items: center;
    display: flex;
    .at-input{
        margin-right: 10px;
        width: 50px;
        height: 40px;;
    }
    Text{
        padding-left:10px ;
    }
}
.navTion{
    color: #b2a500;
}
.imageClass{
    height: 90px;
    width: 90px;
}

二、uni-app 购物车业务逻辑

完整代码 业务逻辑同上

<template>
	<view class="cart">
		<view v-if="flag" class="header">
		  购物车空空如也,请 <navigator open-type="switchTab" url="/pages/home/home">选购商品</navigator>
		</view>
		<view v-else>
		  <view class="prolistItem" v-for="(item , index) of cartlist" :key="index" >
			  <checkbox-group name="" @change="choseFn(index)">
					<checkbox value="cb" :checked="item.cheacked" color="#ff0000" style="transform:scale(0.7)"  />
			  </checkbox-group>
		    <view class="image"> <image :src="item.proimg"></image> </view>
		    <view class="text">
		     <view class="title"> {{item.proname}}</view>
		     <view class="price">{{item.price}}</view>
		    </view>
			<view class="number">
				<text>X{{item.num}}</text>
			</view>
		    <view class="options">
		    	<text @click="reduce(item)" style="padding:5px 10px" >{{"-"}}</text>
		    	<text @click="add(item)" style="background-color: red;">+</text> 
		    	<text @click="del(item, index)">del</text> 
		    </view>
		  </view>
		  <view class="chose">
			  <checkbox-group name="" @change="allChoseFn">
			  	<label><checkbox value="cb" :checked="checked" />{{checked ?'点击全不选' : '点击全选'}}</label>
			  </checkbox-group>
		      
		  	<text>总数量 :{{numbertatol}} </text>
		  	<text>总价格 :¥{{pricetatol}} </text>
		  </view>
		</view>
		
		
		
	</view>
</template>

<script>
	  import { request, Toast } from '../../utils/index.js'
	export default {
		data() {
			return {
				checked:false,
				flag:true,
				cartlist:[],
				numbertatol: 0,
				pricetatol : 0
			};
		},
		
		onShow () { 
			try{
				let userid = uni.getStorageSync('userid')
				let token = uni.getStorageSync('token')
				console.log(token)
				if(userid && token){
					request({
					  url: '/cart',
					  params: {
					    userid, token
					  }
					}).then(res=>{
						if (res.code === '10019') {
						  Toast({str:'请先登录'})
						  uni.navigateTo({
						    url: '/pages/login/login'
						  })
						} else if (res.code === '10012') {
						  Toast({str:'请先选购商品'})
						  this.flag = true
						} else {
							console.log(res)
						  Toast({str:'购物车列表获取成功'})
						  this.flag = false
						  this.cartlist = res.data
						  this.filterData(res.data)
						} 
					})
				}else {
						  Toast({str:'请先登录'})
						  uni.navigateTo({
							url: '/pages/login/login'
						  })
						}
			}catch(e){
				console.log(e)
			}
		},
		methods:{
			// 计算总数量 和 总价格
			allNumberPrice(){
				let numer = 0;
				let price = 0;
				let count= 0;
				this.cartlist.forEach((item,index)=>{
					if(item.cheacked) {
						count ++
						numer += item.num
						price += item.price
					}
				})
				this.numbertatol = numer
				this.pricetatol = price
				if(count === this.cartlist.length) this.checked = true
				else this.checked = false
			},
			// 点击全选 和全部选
			allChoseFn(){
				this.checked = !this.checked
				this.filterData(this.cartlist,this.checked)
				//计算总价格
				this.allNumberPrice()
			},
			// 点击选中改变 总数量和总价
			choseFn(index){
				this.cartlist[index].cheacked = !this.cartlist[index].cheacked
				this.allNumberPrice()
			},
			reduce(item){
				let num = item.num;
				console.log(num)
				if(num>1) {
					num -= 1
					this.numberCompute(num,item,status = "reduce")
				}
				
			},
			add(item){
				let num = item.num + 1
				this.numberCompute(num,item,status = "add")
				
			},
			del(item, index){
				this.numberCompute("",item,index) 
			},
			// 异步请求 同步数据 库
			numberCompute(num,item,status ){
				let token = uni.getStorageSync('token')
				let url = null
				if(status==="reduce" || status === "add") url = "/cart/update"
				else url = "/cart/delete"
				request({
				  url,
				  params :{token,cartid: item.cartid, num : num },
				}).then(res => {
					console.log(res)
				  if (res.code === '10019') {
				    Toast({str:'请先登录'})
				    uni.navigateTo({
				      url: '/pages/login/login'
				    })
				  } else {
				    Toast({str:'修改数量成功'})
					if(status==="reduce") item.num -= 1
					else if (status==="add") item.num +=1
					else{
						this.cartlist.splice(status , 1) // 删除当前的数据
						this.cartlist.length === 0 ? this.flag = true : this.flag = false 
					}
					//计算总价格
					this.allNumberPrice()
				  }
				})
			},
			// 遍历数据  添加cheakbox 
			filterData(cartlist,status=false) {
			   cartlist.map((item,index)=>{
				   return item.cheacked = status
			   })
			}
		}
	}
</script>

<style lang="scss">
	.chose{
		text {
			margin-left: 10px;
		}
	}
.cart {
	.header{
		display: flex;
		navigator{
			color:#4cd964;
		}
	}
}
.number{flex: 1;font: 20px/90px "";}
.number text{
	color: red;
	text-align: center;
}
  .prolistItem {
    height: 100px;
    width: 100%;
    display: flex;
    border-bottom:1rpx solid #ccc;
	image {
	  border: 1px solid #ccc;
	  height: 90px;
	  width: 90px;
	  margin: 5px;
	  box-sizing: border-box
	}
  }
.options{
	flex:1;
	width: 110px;
	display: flex;
	align-items: center;
	text{
		background: #42a44e;
		color: #2C405A;
		padding: 5px;
		margin-left: 10px;
	}
    	
}
.price{
	font-size: 20px;
	
}
.title{
	font-size: 20px;
	width:100%;
	white-space: nowrap;
	text-overflow: ellipsis;
	overflow: hidden;
}
.text {
	width: 100px;
	padding: 3px 5px;
}
</style>

发布了15 篇原创文章 · 获赞 3 · 访问量 656

猜你喜欢

转载自blog.csdn.net/qq_42714690/article/details/104465597