天天看點

vuex 核心概念 state、mutations、actions、getters

核心概念

  • state
  • mutations
  • actions
  • modules

手動引入vuex

如果在vue腳手架中沒有引入vuex需要進行手動配置。

在main.js中添加如下代碼:

import store from 'vuex'

// 在建立vue執行個體時,将store挂載進去
new Vue({
  render: h => h(App),
  store
}).$mount('#app') 
           

state

state中設定資料源,頁面中所有在vuex中存放的資料都要放到store的state中進行存儲。

export default new Vuex.Store({
  state: {
    number: 0
  }
})
           

通路state中資料的兩種方法

  • 通過vue對象進行通路:

    this.$store.state.number

  • 第二種方式:
    • 在元件中導入mapState函數
    • 元件中可以使用mapState函數将需要的資料映射為計算屬性
    • 示例:
// 在需要使用資料的元件中導入該函數
import { mapState } from 'vuex'
export default {
  data () {
    return {}
  },
  components: {
    'my-add': add,
    'my-sub': sub
  },
  // 設定為計算屬性
  computed: {
    ...mapState(['number'])
  }~~
~~} 
           
這樣可以直接通過插值表達式通路number屬性
           

mutations

mutations用于對store中的資料進行變更。

需要注意的是,隻能通過mutations中的函數來變更資料,不能在元件中直接對資料進行更改。

在mutations中定義函數:

mutations: {
  add (state) {
    state.number++
  },
  sub (state) {
    state.number--
  }
},
           

在元件中調用函數需要通過

this.$store.commit

方法:

methods: {
  addOne () {
    this.$store.commit('add')
    console.log('目前值為' + this.$store.state.number)
  }
}
           

調用時傳遞參數

mutations對象中的函數是可以傳遞參數的,如果要傳遞參數至少需要2個形參,第一個位置的形參必須為state,從第二個形參開始才是要接受的參數。

在使用commit調用mutations裡的函數時。第一個實參為要觸發的函數(String類型),第二個實參才是要傳遞的參數。

如下代碼所示:

在vuex中定義:

export default new Vuex.Store({
  state: {
    number: 0
  },
  mutations: {
    add (state) {
      state.number++
    },
    sub (state) {
      state.number--
    },
    // 第一個參數傳遞state
    addN (state, num) {
      state.number += num
    }
  }
})

           

在元件中調用:

methods: {
  addN () {
    this.$store.commit('addN', parseInt(this.addNumber))
    console.log('目前值為' + this.$store.state.number)
  }
}
           
this.addNumber為雙向資料綁定的input值

觸發函數的另一種方式

在元件中導入mapMutations函數:

import { mapMutations } from 'vuex'
           

将需要的函數映射為目前元件中的methods:

methods: {
  ...mapMutations(['addN'])
}
           

這樣可以通過this來調用導入的addN,使用這種方式導入的函數無需傳遞第一個參數如下代碼所示:

<template>
  <div>
    <input type="text" v-model="addNumber">
    <button @click='addMore'>加N</button>
  </div>
</template>
<script>
import { mapMutations } from 'vuex'

export default {
  data () {
    return {
      addNumber: 0
    }
  },
  methods: {
    addMore () {
      // 如果不涉及類型轉換可以直接在@click=調用
      this.addN(parseInt(this.addNumber))
    },
    // 導入addN
    ...mapMutations(['addN'])
  }
}
</script>
<style ></style>
           

不可以在mutations中處理異步代碼

actions

在mutations中不要執行異步操作,應該通過Action來處理異步操作。

在vue的開發工具中:如果是同步代碼,開發工具可以捕獲到值的變換;但是如果是異步代碼,頁面中的值雖然變化了,但是開發工具不能夠捕捉。如下圖所示:

vuex 核心概念 state、mutations、actions、getters
vuex 核心概念 state、mutations、actions、getters

在actions中定義異步代碼

異步代碼在actions中執行,但是仍然需要使用commit去調用mutations的函數将資料進行更改。如下代碼所示:

actions: {
  // actions中的異步代碼必須聲明一個context參數,用來調用mutations中的函數
  asyncAddOne (context) {
    setTimeout(() => {
      // 實質上還是通過調用add方法進行+1
      context.commit('add')
    }, 1000)
  }
}
           

這樣在vuex中異步+1的函數寫好了,如果要觸發actions中的函數需要下面操作。

觸發actions中的異步函數

觸發actions中的異步函數有兩種方法。

通過vue對象觸發

通過dispatch調用actions中的異步代碼,如下代碼所示:

<template>
  <div>
    <button @click='asyncAddOne'>延遲一秒+1</button>
  </div>
</template>

<script>
export default {
  methods: {
    asyncAddOne () {
      this.$store.dispatch('asyncAddOne')
    }
  }
}
</script>
           
vuex 核心概念 state、mutations、actions、getters

千萬不可以使用actions中的函數直接改變值,隻能調用mutations中的函數,使mutations中的函數協助操作值

通過mapActions導入函數

與mapMutations的使用是一樣的

getters

getters用來對state中擷取的資料進行加工,但是不會更改state中的資料。

使用方法:

export default new Vuex.Store({
  state: {},
  mutations: {},
  actions: {},
  // 與state等同級
  getters: {}
})
           

在getters中聲明一個函數,函數中包含要擷取的值和對值進行的加工。如下代碼所示:

getters: {
  showNumber(state) {
    return `目前number值為:${state.number}`
  }
}
           

調用getters中定義的函數,見下文

調用getters中的函數

仍然是兩種方式:vue對象、挂載到計算屬性

vue對象方式

this.$store.getters.showNumber
           

mapGetters方式

  • 導入mapGetters函數
import { mapGetters } from 'vuex' 
           
  • 挂載到計算屬性
computed: {
  ...mapGetters(['showNumber'])
} 
           

繼續閱讀