溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

taro實現購物車邏輯的代碼解析

發(fā)布時間:2020-07-18 10:33:17 來源:億速云 閱讀:311 作者:小豬 欄目:web開發(fā)

這篇文章主要講解了taro實現購物車邏輯的代碼解析,內容清晰明了,對此有興趣的小伙伴可以學習一下,相信大家閱讀完之后會有幫助。

taro 實現購物車邏輯

效果

taro實現購物車邏輯的代碼解析

taro是什么?

Taro 是一套遵循 React 語法規(guī)范的 多端開發(fā) 解決方案。

  • 現如今市面上端的形態(tài)多種多樣,Web、React-Native、微信小程序等各種端大行其道,當業(yè)務要求同時在不同的端都要求有所表現的時候,針對不同的端去編寫多套代碼的成本顯然非常高,這時候只編寫一套代碼就能夠適配到多端的能力就顯得極為需要。
  • 使用 Taro,我們可以只書寫一套代碼,再通過 Taro 的編譯工具,將源代碼分別編譯出可以在不同端(微信/百度/支付寶/字節(jié)跳動/QQ/京東小程序、快應用、H5、React-Native 等)運行的代碼。本代碼是基于Taro UI 開發(fā)的,雖然是基于 taro框架開發(fā)的,但購物車的整體邏輯與微信小程序邏輯是基本一樣的
  • Taro UI是一款基于 Taro 框架開發(fā)的多端 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') { //后端返回的值 ,判斷狀態(tài)
      toast({ title: '登錄已經過期,請從新登錄' })
      Taro.navigateTo({  //跳轉到登錄頁
       url: '/pages/login/index'
      })
     } else if (code === '10012') { 
      this.setState({
       message: '購物車空空如也'
      })
     } else {
     //因為taro是基于react的,在react中,狀態(tài)不能直接改變,要用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 &#63; 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   //實現點擊選中狀態(tài)取反
     this.setState({  
      isactive:active
     })
     if(active===true){ //如果全選,就代表著 購物車的所有商品都被選中,所以,將購物車列表數據全給選中的數組,將單個商品的狀態(tài)全部設為選中
      this.setState({
       check:true,
       activedata:this.state.cartdata
      })
     }else{//否則,選中商品數組為空,將單個商品的狀態(tài)全部設為未選中
      this.setState({
       check:false,
       activedata:[]
      })
     }
    }}>全選</Checkbox>

    <CheckboxGroup  onChange={(evt)=>{ //復選框組,<CheckboxGroup/>中選中項發(fā)生改變是觸發(fā) 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數組中,...是展開運算符,加他是因為在控制臺打印的時候發(fā)現,每個對象外面都加了一個【】,沒辦法,這里應該是有簡單的寫法的,但因為當時累了,也沒有細想,就只能寫成這樣了,
        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) => //循環(huán)顯示購物車數據
       <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輸入框值改變時觸發(fā)的事件,開發(fā)者需要通過 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: '登錄狀態(tài)過期,請重新登錄' })
      Taro.navigateTo({  //跳轉到登錄頁面 
       url: '/pages/login/index'
      })
     }else{ 
       toast({title:'刪除成功!'}) //顯示提示框 封裝的一個方法 其實到這步,商品就已經刪除了,但頁面還沒有發(fā)生變化,所以我們要處理下頁面
       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: '登錄狀態(tài)過期,請重新登錄' })
       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: '登錄狀態(tài)過期,請重新登錄' })
       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 &#63;newitem :item
       // })
       var data=this.state.cartdata //將購物車里邊數據賦給data ,因為在react中,狀態(tài)不能直接改變
       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實現購物車邏輯的代碼解析有進一步的了解,如果還想學習更多內容,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI