10分鐘學(xué)會vuex

Vuex全局的狀態(tài)統(tǒng)一管理,解決組件之間狀態(tài)共享和數(shù)據(jù)通信的問題。

第一步

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex) // 使用插件
// 導(dǎo)出store實例
export default new Vuex.Store({
  state: {

  },
  mutations: {

  },
  actions: {

  }
})

第二步

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store, // 增加store屬性,值是導(dǎo)出store的實例
  render: h => h(App)
}).$mount('#app')

通過上面兩個步驟,每個組件中都有了$store屬性,就是我們創(chuàng)建的容器。里面有commit,dispatch,state,getters,actions,mutations,在每個組件中可以通過this.$store打印出來看看。

開始使用

定義狀態(tài)

export default new Vuex.Store({
  state: {
    count: 1 // state中定義響應(yīng)式的數(shù)據(jù)
  }
})

使用狀態(tài):在store的state中定義的狀態(tài)count,在組件中可以使用this.$store.state.count獲取。


定義mutations

在store的mutations中添加對應(yīng)的方法

export default new Vuex.Store({
  state: {
    count: 1 // state中定義響應(yīng)式的數(shù)據(jù)
  },
  mutations: {
    addTen (state, num) {
        state.count = state.count + num
    }
  },
  actions: {

  }
})

提交mutations
組件中通過commit提交mutations去修改state中的狀態(tài)

this.$store.commit('addTen', 10)

定義actions
在store的actions中添加對應(yīng)的方法

export default new Vuex.Store({
  state: {
    count: 1
  },
  mutations: {
    addTen (state, num) {
        // 第一個參數(shù)是狀態(tài),第二個是傳入的參數(shù)
        state.count = state.count + num
    }
  },
  actions: {
    minusTen ({commit}, num) {
        // 第一個參數(shù)是store實例,第二個是傳入的參數(shù)
        setTimeout(() => {
            commit('addTen', num)
        }, 1000)
    }
  }
})

派發(fā)動作
組件中可以使用dispatch派發(fā)一個動作,來觸發(fā)actions中的方法,actions可以異步的提交mutations去修改state中的狀態(tài)

this.$store.dispatch('minusTen', 10)

actions主要是復(fù)用,封裝代碼,處理異步,請求接口等等,真正修改狀態(tài)放到了mutations中處理


定義getters
在store的getters中添加對應(yīng)的方法

export default new Vuex.Store({
  state: {
    count: 1,
    person: {
        name: '張三'
    }
  },
  getters: {
    getName (state) {
        // getters是同步的
        return state.person.name
    }
  }
})

使用getters

this.$store.getters.getName

getters定義的方法相當于計算屬性,相當于定義在computed一樣,有緩存,依賴改變會重新計算。

組件代碼演示

<template>
  <div class="hello">
    <h1>{{ this.$store.state.count }}</h1>
    <h1>{{ this.$store.getters.getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
export default {
  methods: {
    syncAdd () {
      this.$store.commit('addTen', 10)
    },
    asyncAdd () {
      this.$store.dispatch('minusTen', 10)
    }
  }
}
</script>

簡寫

上面的寫法都是在this.$store中獲取屬性或方法進行操作。

this.$store.state.count
this.$store.getters.getName
this.$store.commit('addTen', 10)
this.$store.dispatch('minusTen', 10)

但是這些操作寫起來比較繁瑣,每次都要寫this.$store,為了簡寫,所以vuex提供了一些映射的方法,直接導(dǎo)入到組件中就可以使用了。

<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <h1>{{ getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
import {mapActions, mapState, mapMutations, mapGetters} from 'vuex'
export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['getName'])
  },
  methods: {
    syncAdd () {
      this.addTen(10)
    },
    asyncAdd () {
      this.minusTen(10)
    },
    ...mapActions(['minusTen']),
    ...mapMutations(['addTen'])
  }
}
</script>

有一點需要說明的是,使用擴展運算符,表示這些方法返回的都是對象,mapStatemapGetters需要定義在計算屬性中,因為他們定義的數(shù)據(jù)是響應(yīng)式的。而mapActionsmapMutations需要定義在methods中。

拆分模塊

狀態(tài)是可以分層的,當一個項目維護的狀態(tài)太多,可以拆分成單獨的模塊,在定義store中有個modules屬性,里面可以定義單獨的模塊。

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    'page1': {
      namespaced: true,
      state: {
        count: 1,
        person: {
          name: '張三'
        }
      },
      mutations: {
        addTen (state, num) {
          state.count = state.count + num
        }
      },
      actions: {
        minusTen ({commit}) {
          setTimeout(() => {
            commit('addTen', 10)
          }, 1000)
        }
      },
      getters: {
        getName (state) {
          return state.person.name
        }
      }
    }
  }
})

在組件中這樣用

<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <h1>{{ getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
import {mapActions, mapState, mapMutations, mapGetters} from 'vuex'
export default {
  computed: {
    ...mapState('page1', ['count']),
    ...mapGetters('page1', ['getName'])
  },
  methods: {
    syncAdd () {
      this.addTen(10)
    },
    asyncAdd () {
      this.minusTen(10)
    },
    ...mapActions('page1', ['minusTen']),
    ...mapMutations('page1', ['addTen'])
  }
}
</script>

每個方法都傳了兩個參數(shù),第一個參數(shù)指定命名空間,第二個參數(shù)是對應(yīng)的屬性,為了進一步簡寫,可以通過幫助函數(shù)指定命名空間,指定當前組件在使用的模塊。

<template>
  <div class="hello">
    <h1>{{ count }}</h1>
    <h1>{{ getName }}</h1>
    <button @click="syncAdd">同步加10</button>
    <button @click="asyncAdd">異步加10</button>
  </div>
</template>

<script>
import { createNamespacedHelpers } from 'vuex'
// 創(chuàng)建幫助函數(shù)指定命令空間
let { mapActions, mapState, mapMutations, mapGetters } = createNamespacedHelpers('page1')

export default {
  computed: {
    ...mapState(['count']),
    ...mapGetters(['getName'])
  },
  methods: {
    syncAdd () {
      this.addTen(10)
    },
    asyncAdd () {
      this.minusTen(10)
    },
    ...mapActions(['minusTen']),
    ...mapMutations(['addTen'])
  }
}
</script>

不使用簡寫

this.$store.getters['page1/getName']
this.$store.state.page1.count
this.$store.commit('page1/addTen', 10)
this.$store.dispatch('page1/minusTen', 10)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 安裝 npm npm install vuex --save 在一個模塊化的打包系統(tǒng)中,您必須顯式地通過Vue.u...
    蕭玄辭閱讀 3,038評論 0 7
  • vuex 場景重現(xiàn):一個用戶在注冊頁面注冊了手機號碼,跳轉(zhuǎn)到登錄頁面也想拿到這個手機號碼,你可以通過vue的組件化...
    sunny519111閱讀 8,163評論 4 111
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 788評論 0 3
  • Vuex是什么? Vuex 是一個專為 Vue.js應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件...
    蕭玄辭閱讀 3,232評論 0 6
  • ### store 1. Vue 組件中獲得 Vuex 狀態(tài) ```js //方式一 全局引入單例類 // 創(chuàng)建一...
    蕓豆_6a86閱讀 444評論 0 0

友情鏈接更多精彩內(nèi)容