成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

taro實(shí)現(xiàn)購(gòu)物車(chē)邏輯的代碼解析

這篇文章主要講解了taro實(shí)現(xiàn)購(gòu)物車(chē)邏輯的代碼解析,內(nèi)容清晰明了,對(duì)此有興趣的小伙伴可以學(xué)習(xí)一下,相信大家閱讀完之后會(huì)有幫助。

創(chuàng)新互聯(lián)公司堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的興安盟烏蘭浩特網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

taro 實(shí)現(xiàn)購(gòu)物車(chē)邏輯

效果

taro實(shí)現(xiàn)購(gòu)物車(chē)邏輯的代碼解析

taro是什么?

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

  • 現(xiàn)如今市面上端的形態(tài)多種多樣,Web、React-Native、微信小程序等各種端大行其道,當(dāng)業(yè)務(wù)要求同時(shí)在不同的端都要求有所表現(xiàn)的時(shí)候,針對(duì)不同的端去編寫(xiě)多套代碼的成本顯然非常高,這時(shí)候只編寫(xiě)一套代碼就能夠適配到多端的能力就顯得極為需要。
  • 使用 Taro,我們可以只書(shū)寫(xiě)一套代碼,再通過(guò) Taro 的編譯工具,將源代碼分別編譯出可以在不同端(微信/百度/支付寶/字節(jié)跳動(dòng)/QQ/京東小程序、快應(yīng)用、H5、React-Native 等)運(yùn)行的代碼。本代碼是基于Taro UI 開(kāi)發(fā)的,雖然是基于 taro框架開(kāi)發(fā)的,但購(gòu)物車(chē)的整體邏輯與微信小程序邏輯是基本一樣的
  • Taro UI是一款基于 Taro 框架開(kāi)發(fā)的多端 UI 組件庫(kù)
     

需要安裝taro ui

$ npm install taro-ui

taro官方文檔

taroUI 官方文檔

cart/index.jsx頁(yè)面代碼
import Taro, { Component } from '@tarojs/taro'
import { View, Checkbox, CheckboxGroup } from '@tarojs/components' 
//用到了taro的三個(gè)組件
//想了解可以去查看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: '', //購(gòu)物車(chē)為空時(shí)顯示的信息
   cartdata: [], //購(gòu)物車(chē)的數(shù)據(jù)列表
   isactive: false, //全選按鈕是否選中
   check:false, //單個(gè)商品購(gòu)物車(chē)是否被選中
   totalnum:0, //總數(shù)量
   totalprice:0, //總價(jià)格
   activedata:[] //復(fù)選框選中的數(shù)據(jù)列表
  }

 }
 componentDidShow () {
  //獲取購(gòu)物車(chē)數(shù)據(jù)
  try {
   const token = Taro.getStorageSync('token') //這兩個(gè)數(shù)據(jù)是我在登錄頁(yè)面,登錄時(shí)添加到本地的token和用戶id
   const userid = Taro.getStorageSync('userid')
   if (token) { //如果登錄了
    const usrename = Taro.getStorageSync('username') //同樣登錄時(shí)添加到本地的用戶名
    Taro.setNavigationBarTitle({ //改變導(dǎo)航欄的標(biāo)題
     title: usrename + '---購(gòu)物車(chē)'
    })
    request({ //這里的request是封裝后的方法
     url: '/cart', //接口
     data: { //需要傳遞的數(shù)據(jù)
      token,
      userid
     }
    }).then(res => { 
     console.log(res.data)
     const { code } = res.data 
     if (code === '10119') { //后端返回的值 ,判斷狀態(tài)
      toast({ title: '登錄已經(jīng)過(guò)期,請(qǐng)從新登錄' })
      Taro.navigateTo({  //跳轉(zhuǎn)到登錄頁(yè)
       url: '/pages/login/index'
      })
     } else if (code === '10012') { 
      this.setState({
       message: '購(gòu)物車(chē)空空如也'
      })
     } else {
     //因?yàn)閠aro是基于react的,在react中,狀態(tài)不能直接改變,要用this.setState
      this.setState({ //登錄成功,購(gòu)物車(chē)有數(shù)據(jù)時(shí),將購(gòu)物車(chē)的列表數(shù)據(jù)添加到購(gòu)物車(chē)數(shù)據(jù)中 
       cartdata: res.data.data
      })
     }
    })
   } else { //如果沒(méi)登錄
    toast({ title: '請(qǐng)登錄' })
    Taro.navigateTo({ //跳轉(zhuǎn)到登錄頁(yè)面
     url: '/pages/login/index'
    })
   }

  } catch (e) {

  }
 }
 componentDidUpdate(){
  //計(jì)算總數(shù)量,總價(jià)格
  let num=0;
  let price=0;
  if(this.state.activedata.length!=0){ //如果選中的數(shù)組長(zhǎng)度不為0時(shí),就是有商品被選中了
   this.state.activedata.map((item)=>{ //map遍歷數(shù)組
    num+= +item.num  //將數(shù)量相加 + 號(hào)為一元運(yùn)算符,將字符串類型轉(zhuǎn)換為數(shù)值類型
    price+=item.num*item.price  //求價(jià)格
   }) 
   this.setState({ //設(shè)置值
    totalnum:num,
    totalprice:price
   })
  }else{ //如果沒(méi)有商品被選中
   this.setState({
    totalnum:0,
    totalprice:0
   })
  }
  
 }
 render() {
  return ( //結(jié)構(gòu)開(kāi)始
   <View>{
    this.state.message.length === 0 &#63; null : //如果 message不為空的話,就代表著購(gòu)物車(chē)沒(méi)有數(shù)據(jù),所以顯示購(gòu)物車(chē)空空如也,去選購(gòu),如果為空,代表著購(gòu)物車(chē)有數(shù)據(jù),不顯示
     <View onClick={() => { //點(diǎn)擊事件 去主頁(yè)選購(gòu)商品
      Taro.switchTab({
       url: '/pages/home/index'
      })
     }}> {this.state.message}去選購(gòu)</View>
   }
    <Checkbox checked={this.state.isactive} onClick={()=>{ //全選按鈕 check代表著按鈕是否選中 因?yàn)閠aro中的checkbox的onchange方法,不支持小程序,所以沒(méi)辦法,只能用 onClick方法
     let active=!this.state.isactive   //實(shí)現(xiàn)點(diǎn)擊選中狀態(tài)取反
     this.setState({  
      isactive:active
     })
     if(active===true){ //如果全選,就代表著 購(gòu)物車(chē)的所有商品都被選中,所以,將購(gòu)物車(chē)列表數(shù)據(jù)全給選中的數(shù)組,將單個(gè)商品的狀態(tài)全部設(shè)為選中
      this.setState({
       check:true,
       activedata:this.state.cartdata
      })
     }else{//否則,選中商品數(shù)組為空,將單個(gè)商品的狀態(tài)全部設(shè)為未選中
      this.setState({
       check:false,
       activedata:[]
      })
     }
    }}>全選</Checkbox>

    <CheckboxGroup  onChange={(evt)=>{ //復(fù)選框組,<CheckboxGroup/>中選中項(xiàng)發(fā)生改變是觸發(fā) change 事件,detail = value:[選中的 Checkbox 的 value 的數(shù)組]
     const {detail:{value}}=evt 
     if(value.length===this.state.cartdata.length){ //選中的數(shù)組的長(zhǎng)度如果等于購(gòu)物車(chē)列表的長(zhǎng)度是全選
      this.setState({  
       isactive:true,  //全選按鈕被選中
       activedata:this.state.cartdata  //選中商品數(shù)組為購(gòu)物車(chē)的列表數(shù)組
      })
     }else{ //否則未全選
      var i;
      var data=[];
      for ( i in value){  //因?yàn)関alue數(shù)組里的值為選中的checkbox的value的值,我設(shè)置的為cartid
       data.push(...(this.state.cartdata.filter(item=>{ //過(guò)濾下購(gòu)物車(chē)的列表數(shù)據(jù),將cartid相等的對(duì)象取出來(lái),放進(jìn)data數(shù)組中,...是展開(kāi)運(yùn)算符,加他是因?yàn)樵诳刂婆_(tái)打印的時(shí)候發(fā)現(xiàn),每個(gè)對(duì)象外面都加了一個(gè)【】,沒(méi)辦法,這里應(yīng)該是有簡(jiǎn)單的寫(xiě)法的,但因?yàn)楫?dāng)時(shí)累了,也沒(méi)有細(xì)想,就只能寫(xiě)成這樣了,
        return item.cartid==value[i]
       })))
      }
      console.log(data,this.state.cartdata)
      this.setState({
       isactive:false,//全選按鈕未被選中
       activedata:data //設(shè)置選中商品的數(shù)組
       //至此,計(jì)算總數(shù)量,總價(jià)格、全選、單選的邏輯就全完成了,至于為什么寫(xiě)成這樣,是因?yàn)閠aro是基于react的標(biāo)準(zhǔn)的,沒(méi)有計(jì)算屬性,沒(méi)有雙向綁定
      })
     }
    }}>
     {
      this.state.cartdata.map((item, index) => //循環(huán)顯示購(gòu)物車(chē)數(shù)據(jù)
       <AtCard
        title={item.proname}
        thumb={item.proimg}
        extra={'$'+item.price}
        key={item.proid}

       >
        <View><Checkbox value={item.cartid} checked={this.state.check}></Checkbox> 
        {/* 每個(gè)商品前的復(fù)選框 */}
         <AtInputNumber //數(shù)量加減
          min={0}
          max={10}
          step={1}
          value={item.num} //之間的值
          onChange={this.change.bind(this, item,index)} //onchange輸入框值改變時(shí)觸發(fā)的事件,開(kāi)發(fā)者需要通過(guò) onChange 事件來(lái)更新 value 值變化,onChange 函數(shù)必填
         />
         <AtButton type='primary' size='small' onClick={this.del.bind(this,item)}>刪除</AtButton> 
         {/* 刪除按鈕 */}
        </View>

       </AtCard>
      )
     }
    </CheckboxGroup>
    <View>總數(shù)量:{this.state.totalnum}</View>
    <View>總價(jià)格:{this.state.totalprice}</View>
   </View>
  )
 }
 del(item){ //刪除方法
 //item代表著商品的數(shù)據(jù) 
  try{
   const token = Taro.getStorageSync('token')
   if(token){ //如果有token值
    request({ //數(shù)據(jù)請(qǐng)求   刪除接口
     url: '/cart/delete',
     data: {
      token,
      cartid: item.cartid
     }
    }).then(res => {
     const { code } = res.data
     if (code === '10119') { //后端接口 返回值
      toast({ title: '登錄狀態(tài)過(guò)期,請(qǐng)重新登錄' })
      Taro.navigateTo({  //跳轉(zhuǎn)到登錄頁(yè)面 
       url: '/pages/login/index'
      })
     }else{ 
       toast({title:'刪除成功!'}) //顯示提示框 封裝的一個(gè)方法 其實(shí)到這步,商品就已經(jīng)刪除了,但頁(yè)面還沒(méi)有發(fā)生變化,所以我們要處理下頁(yè)面
       let id=item.cartid    
       let data1=this.state.cartdata.filter(item=>{ //過(guò)濾下不等于被刪除的商品id,將未刪除的商品,放到data1中
        return item.cartid!=id
       })
       let data2=this.state.activedata.filter(item=>{ //在選中情況下
        return item.cartid!=id
       })
       this.setState({ //設(shè)置下購(gòu)物車(chē)列表數(shù)據(jù) 
        cartdata:data1,
        activedata:data2
       })
     }
    })
   }else{ //如果沒(méi)有token值
    toast({ title: '請(qǐng)登錄' }) 
    Taro.navigateTo({ //跳轉(zhuǎn)到登錄頁(yè)面
     url: '/pages/login/index'
    })
   }
  }catch(e){
    
  }
 }
 change(item,index,evt) {
  //數(shù)量改變
  console.log(evt) 
  //item代表著商品的數(shù)據(jù) 
  //index,為當(dāng)前改變的是那個(gè)商品的值, 
  //evt為改變后的數(shù)值
  try {
   const token = Taro.getStorageSync('token') 
   if (token) { //如果有token值
    if (evt === '0') { //數(shù)量為0 我設(shè)置的為刪除商品,與上面的刪除一致,這里我就不再解釋了
     request({
      url: '/cart/delete',
      data: {
       token,
       cartid: item.cartid
      }
     }).then(res => {
      const { code } = res.data
      if (code === '10119') {
       toast({ title: '登錄狀態(tài)過(guò)期,請(qǐng)重新登錄' })
       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') {  //后端驗(yàn)證
       toast({ title: '登錄狀態(tài)過(guò)期,請(qǐng)重新登錄' })
       Taro.navigateTo({ //跳轉(zhuǎn)到登錄頁(yè)
        url: '/pages/login/index'
       })
      }else{
        toast({title:'更新成功!'})
        item.num=evt //改變下數(shù)量
       // var newitem=item
       // var data=this.state.cartdata.map(item=>{
       //  return item.cartid===newitem.cartid &#63;newitem :item
       // })
       var data=this.state.cartdata //將購(gòu)物車(chē)?yán)镞厰?shù)據(jù)賦給data ,因?yàn)樵趓eact中,狀態(tài)不能直接改變
       data[index]=item // 將新的對(duì)象賦給數(shù)組的第index對(duì)象
       this.setState({ //設(shè)置下
        cartdata:data
       })
      }
     })
    }
   } else {//如果沒(méi)有token值
    toast({ title: '請(qǐng)登錄' })
    Taro.navigateTo({
     url: '/pages/login/index'
    })
   }

  } catch (e) {

  }

 }
}

export default Index
cart/index.scss頁(yè)面代碼
@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 ='',//接口就不放上去了,因?yàn)橐膊皇俏业?,這里就放接口前的公共網(wǎng)址
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({ //數(shù)據(jù)請(qǐng)求 與小程序類似
   url: publicurl+url,
   data:data || {},
   method:method || 'GET',
   success(res){ 
    //成功
    resolve(res)
   },
   fail(err){
    //失敗
    reject(err)
   },
   complete(){
    // complete 接口調(diào)用結(jié)束的回調(diào)函數(shù)
    wx.hideLoading(); //隱藏loading框
   }
  })
 })
}

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

看完上述內(nèi)容,是不是對(duì)taro實(shí)現(xiàn)購(gòu)物車(chē)邏輯的代碼解析有進(jìn)一步的了解,如果還想學(xué)習(xí)更多內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

當(dāng)前標(biāo)題:taro實(shí)現(xiàn)購(gòu)物車(chē)邏輯的代碼解析
文章轉(zhuǎn)載:http://jinyejixie.com/article12/gpiigc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、網(wǎng)站制作、移動(dòng)網(wǎng)站建設(shè)、營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁(yè)設(shè)計(jì)
徐汇区| 临高县| 义马市| 大庆市| 大关县| 鄂尔多斯市| 洛川县| 肥西县| 平和县| 和平县| 株洲市| 洞口县| 武平县| 成安县| 岑巩县| 新郑市| 忻州市| 哈密市| 阜南县| 略阳县| 平阳县| 西安市| 双鸭山市| 阿拉善左旗| 彰化县| 永城市| 民勤县| 曲沃县| 武汉市| 湘阴县| 浦北县| 秀山| 吴桥县| 嘉定区| 溧水县| 塔河县| 依安县| 当涂县| 舟山市| 吉水县| 图们市|