首先, 介紹一下vuex是個什么東西, 個人理解來說, vuex就是一個狀態管理的東西, 它里面有且僅有一個Store倉庫, 這個倉庫里面存放着一些變量, 為什么要有這么一個變量呢, 用過vue的人肯定都清除, 父子組件之間的通訊傳值是個比較麻煩的事情, 特別是, 嵌套組件特別多的時候, 這種情況下, 一級一級地傳遞下去十分麻煩, 還有就是兄弟組件之間的傳值也一樣麻煩. 而vuex中的Store這個倉庫, 就能夠為我們將放在這個倉庫中的值, 分發給整個項目下的所有組件, 也就是說是, 不用一級一級地向下傳值, 所有組件就都可以共享這些變量. 今天主要想說的就是在組件化開發中, 如何使用vuex的一個簡單入門級的小例子, 先介紹一下組件和文件結構:
一個是主組件App.vue, 一個是子組件page1.vue, 將子組件渲染在主組件App.vue中, 新建一個文件夾vuex, 在里面放置了store.js文件
首先, 安裝vuex
npm i vuex
在store.js文件中, 引入vue和vuex的包, 並實例化暴露Store對象,設置其中的數據
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({
state: {
count: 0
}
})
在main.js中設置vue實例, 引入store對象
//.. import store from './vuex/store' Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ //.. store, components: { App }, template: '<App/>' })
我們現在已經在這個store倉庫里放了一個數據了, 現在要做的就是在子組件中將這個store中的數據獲取到, 我們可以在組件的計算屬性computed中, 使用this.$store.state.數據的方式, 獲取store中想要的數據
<template> <div> <span>{{count}}</span> </div> </template> <script> export default { //.. computed: { count() { return this.$store.state.count } }, } </script>
我們可以在這個子組件中, 把store打印出來, 看一下是什么樣子的
從這里就可以看到在store中有一個state對象,就是我們設置的值, 但是, 如果想要改變值就需要用到store對象中的mutations方法, mutations是唯一可以改變store中的數據的值的方式, 它里面可以定義一個函數, 接收state, 比如, 我們想要在子組件中, 改變store中count的值, 就需要在store的實例中, 定義一個類型的方法, 讓count的值增加, 然后, 再在子組件中, 定義一個方法, 來喚醒mutations中指定類型的方法,從而達到改變count值, 比如, 我在store實例的mutations中定義了一個類型為add的方法, 然后再在子組件中, 通過this.$store.commit('add')改變了count的值
export default new Vuex.Store({ state: { count: 0, }, mutations: { add() { this.state.count++ }, } })
<template> <div> <span>{{count}}</span> <button @click="addCount">+</button> </div> </template> <script> export default { /.. computed: { count() { return this.$store.state.count } }, methods: { addCount() { this.$store.commit('add') } } } </script>
此外, mutations是支持傳入額外的參數的
this.$store.commit('add',2)
add(state,n) {
state.count += n },
其實, 在store中, 也有一個類似於vue中計算屬性computed的屬性, 叫做getters, getters的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。它的第一個參數接收state
export default new Vuex.Store({ state: { info: [ {id: 1, name: 'zs'}, {id: 2, name: 'ls'}, {id: 3, name: 'ww'}, {id: 4, name: 'zl'} ] }, //.. getters: { getInfo(state) { return state.info.filter(item => { return item.id === 1 }) } } })
如果想要在子組件中顯示getters中getInfo的返回值, 需要在子組件的computed屬性中, 用this.$store.getters.getInfo的方式獲取, 要注意的是, 如果在getInfo中, 不將state傳入進去, 那么子組件在獲取的時候, 是會報錯的
<template> <div> <p>{{userInfor}}</p> </div> </template> <script> export default { //.. computed: { userInfor() { return this.$store.getters.getInfo[0].name } } } </script>
現在, 我們要注意的一點就是, mutations 必須是同步的, 因為,如果我們正在 debug 一個 app 並且觀察 devtool 中的 mutation 日志。每一條 mutation 被記錄,devtools 都需要捕捉到前一狀態和后一狀態的快照 如果mutations中有一個回調函數, 那么當mutations觸發時, 其中的回調函數或者定時器暫時還並沒有被執行,devtools 不知道什么時候回調函數實際上被調用, 這時候, 就需要利用store中的actions來幫助我們改變數據了, actions只是提交mutations,而不是像mutations一樣直接改變數據, 並且, actions中可以有任意的異步函數,在子組件中,需要利用this.$store.dispach的方式, 分發actions
export default new Vuex.Store({ state: { count: 0, }, mutations: { min(state,n) { state.count -= n.amount } }, actions: { increment ({commit},n) { setInterval(()=>{ commit('min',n) },1000) } } })
minCount() { this.$store.dispatch({ type: 'increment', amount: 2 }) }