Vuex(實現加減操作,Vue.set解決自定義屬性沒有雙向數據綁定)


一、前言                                                                    

二、主要內容                                                             

1、效果

      

 

 

2、分析:

             1)點擊按鈕進行加減操作,肯定要注冊一個點擊事件,可以給這個點擊事件傳入一個標識,讓他區別什么時候加,什么時候減

             2)現在是將加減這一部分單獨提取出來的一個公共主鍵,所以還需要區分每一個主鍵

             3)父組件中在遍歷的時候,(food, index) in goods  可以用food來區分每一項

             4)從父組件哪里傳進來一個food屬性(:food="food"),

             5)子組件接收到這個food屬性,

             6)我們用vuex來管理我們的數據狀態,所以操作數據的部分盡量在vuex中進行

3、具體實現

             1)父組件中傳入自定義屬性

<!--父組件shopGoods中定義自定義屬性food,並且傳入-->
<li class="food-item bottom-border-1px" v-for="(food, index) in good.foods" :key="index">
               
   <div class="cartcontrol-wrapper">
    <CartControl :food='food'></CartControl>
   </div>
</li>

             2)子組件中接收,並且使用,接收的目的是為了區分每一項

props: { //接收傳入的food
        food: {
            type: Object
        }
    },

 

             3)給“+”,“-”注冊點擊事件,傳進去一個標識,true==加操作, false==減操作

    <transition name="move">
          <div class="iconfont iconremove_circle_outline" v-if="food.count" @click="updateFoodCount(false)"></div>
    </transition>
        <div class="cart-count">{{food.count}}</div>
        <div class="iconfont iconadd_circle" @click="updateFoodCount(true)"></div>
   

             4)點擊操作執行的時候同時發送一個dispatch交給vuex去處理狀態數據

 methods:{
      updateFoodCount(isAdd){
        //如果為true就加
        //如果為false就減
        //但是這里加減不能直接在組件里面寫,將這些操作交給vuex處理
        //food.count++
        //要傳遞參數:需要讓后台識別是加還是減:isAdd, 需要讓后台知道是哪一個food發生變化,所以需要傳過去這兩個
        //food一定要加this
        this.$store.dispatch("updateFoodCount",{isAdd,food: this.food})
      }
    }
    

           5)vuex結構目錄(下面將根據代碼執行的步驟來分析)

                 

 

 

         6)先提交到actions.js里面,actions接收到傳過來的參數,根據參數判斷加還是減,

//同步更新count,因為不需要去后台后去數據,接收到前面獲取的參數isAdd,food
  updateFoodCount({commit},{isAdd, food}){

      //然后判斷isAdd=true 加, isAdd=false 減
      if(isAdd){
          //true就commit mutation中的RECEIVE_ADD_COUNT和RECEIVE_DECRESS_COUNT
          commit(RECEIVE_ADD_COUNT,{food})
      }else{
          commit(RECEIVE_DECRESS_COUNT,{food})
      }

  }

        7)actions.js中commit到mutations.js中分別根據isAdd的值,去執行不同的函數

//actions.js中commit執行這里的函數
  //加操作
[RECEIVE_ADD_COUNT](state,{food}){
            //如果沒有food.count,點一下就加上了這個自定義屬性
            //由於這個自定義屬性不是響應式的數據,可以用vue插件看到數據改變了,但是視圖並沒發生變化
            if(!food.count){
                  //food.count=1,視圖沒有出現
                 // food.count=1
                  Vue.set(food, 'count', 1)  //手動添加數據雙向綁定

            }else{
                  food.count++
            }
      },

      //減操作

      [RECEIVE_DECRESS_COUNT](state,{food}){
            food.count--
            if(food.count<=0){
                  food.count=0;
            }

      }

 

 

 

 

<template>
  <div class="cartcontrol">
    <transition name="move">
      <div class="iconfont icon-remove_circle_outline" v-if="food.count" @click.stop="updateFoodCount(false)"></div>
    </transition>
    <div class="cart-count" v-if="food.count">{{food.count}}</div>
    <div class="iconfont icon-add_circle" @click.stop="updateFoodCount(true)"></div>
  </div>
</template>

<script>
  export default {
    props: {
      food: Object
    },

    methods: {
      updateFoodCount (isAdd) {
        this.$store.dispatch('updateFoodCount', {isAdd, food: this.food})
      }
    }
  }
</script>

<style lang="stylus" rel="stylesheet/stylus">
  @import "../../common/stylus/mixins.styl"
  .cartcontrol
    font-size: 0
    .cart-decrease
      display: inline-block
      padding: 6px
      line-height: 24px
      font-size: 24px
      color: rgb(0, 160, 220)

    .icon-remove_circle_outline
      display: inline-block
      padding 6px
      line-height 24px
      font-size 24px
      color $green
      &.move-enter-active, &.move-leave-active
        transition all .3s
      &.move-enter, &.move-leave-to
        opacity 0
        transform translateX(15px) rotate(180deg)
    .cart-count
      display: inline-block
      vertical-align: top
      width: 12px
      padding-top: 6px
      line-height: 24px
      text-align: center
      font-size: 10px
      color: rgb(147, 153, 159)
    .icon-add_circle
      display: inline-block
      padding: 6px
      line-height: 24px
      font-size: 24px
      color $green
</style>
CartControl

 

 

三、總結                                                                    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM