當用Vue CLI 3初始化一個Vue的項目以後,關於Vuex的內容,默認是寫在 src/store.js 文件中的。vue
因此,咱們能夠對Vuex進行分層,使不一樣的模塊區分開來。es6
原目錄是:vuex
src/store.js
複製代碼
更改後的目錄:api
src
-- store
-- modules
-- cart.js // 購物車
-- product.js // 商品列表
-- xxx.js // 其餘的,能夠是 user.js,用戶管理
-- index.js // 將原來的src/store.js移動到store目錄,並重命名爲 index.js
-- mutation-types.js // 存儲一些變量的名字
複製代碼
namespaced是命名空間的意思。bash
先創建一些變量:函數
mutation-types.js:ui
// api的列表
export const GET_PRODUCT_LIST = 'GET_PRODUCT_LIST'; // 獲取商品列表
複製代碼
先編寫兩個模塊:this
cart.js:spa
// 爲了防止cart.js 和product.js 中的actions相互衝突,
// 須要引入一個命名空間的概念,這樣cart.js 和 product.js 中的都有用
export default {
state: {
carts:[]
},
actions: {
}
}
複製代碼
product.js:code
import * as types from '../mutation-types';
export default {
namespaced: true,
state: {
products: []
},
actions: {
// [types.GET_PRODUCT_LIST]的意思是當前變量去取值
// 至關於 getProductList(){}
[types.GET_PRODUCT_LIST]({ commit}, payload){
console.log('xxxx');
}
}
}
複製代碼
src/store/index.js:
import Vue from 'vue'
import Vuex from 'vuex'
import cart from './modules/cart' // 引入其餘分層的模塊
import product from './modules/product'
Vue.use(Vuex)
export default new Vuex.Store({
// 若是須要引入模塊中的狀態,須要用到 modules
modules: {
cart,
product
},
state: {
// xxx
},
mutations: {
},
actions: {
}
})
複製代碼
在Home.vue組件中,去觸發actions中的方法。
通常在actions裏面,去請求後臺接口。也就是說,把請求接口的方法,寫在actions裏面。而後在組件中去觸發。
Home.vue:
<template>
<div class="home">
商品頁
</div>
</template>
<script>
import * as types from '../store/mutation-types'
export default {
mounted(){
// 1.第一種觸發actions的方式:使用this.$store.dispatch方法
// 觸發actions
// 'product/' + types.GET_PRODUCT_LIST是指定product.js模塊下的actions方法
this.$store.dispatch('product/'+ types.GET_PRODUCT_LIST)
}
}
</script>
複製代碼
Home.vue:
<template>
<div class="home">
商品頁
</div>
</template>
<script>
import { mapActions } from 'vuex'
import * as types from '../store/mutation-types'
export default {
methods: {
// 'product' 指的是product.js 這個模塊
// [type.GET_PRODUCT_LIST] 指的是變量取值
...mapActions('product', [types.GET_PRODUCT_LIST])
},
mounted(){
// 2.第二種觸發actions的方式:使用 mapActions
this[types.GET_PRODUCT_LIST]()
}
}
</script>
複製代碼
Home.vue:
<template>
<div class="home">
商品頁
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
let { mapActions } = createNamespacedHelpers('product') // 建立product的命名空間
import * as types from '../store/mutation-types'
export default {
methods: {
// 配合createNamespacedHelpers幫助方法使用
// 已經指定命名空間,不須要在...mapActions()中指定
...mapActions([types.GET_PRODUCT_LIST])
},
mounted(){
// 2.第二種觸發actions的方式:使用 mapActions
this[types.GET_PRODUCT_LIST]()
}
}
</script>
複製代碼
getters,相似於computed
state和getters都屬於 Vuex的屬性。
好比,咱們要把state狀態的數據進行一次映射或者篩選,再把這個結果從新計算並提供組件使用。舉個例子:
store.js:
state: {
arr: [
{id: 1, name: 'iissoft',score: 80},
{id: 2, name: 'steven', score:60},
{id: 3, name: 'jerry', score:90}
]
},
getters: {
arrList: function (state) { //這裏咱們對狀態進行映射,進行從新計算
return state.arr.map(function(item){
return item.score >= 60 ? '及格' : '不及格';
})
}
}
複製代碼
此時,getters會暴露一個store.getters 對象,咱們就能夠在任何組件中使用 this.$store.getters.xxx來綁定數據。
在組件中調取getters中的數據。 header.vue:
<template>
<div>
<ul>
<li v-for="item in arrList">{{item}}</li>
</ul>
</div>
</template>
<script>
export default {
computed: {
arrList: function (){
return this.$store.getters.arrList; //經過store.getters對象來訪問
}
}
}
</script>
複製代碼
另外一種方式,來調取getters中的數據。
Vuex給咱們提供了另外一個方法mapGetters。
store.js:
state: {
arr: [ //狀態
{id: 1, name: 'iissoft', score: 80 },
{id: 2, name: 'steven', score: 60},
{id: 3, name: 'jerry', score: 90}
]
},
getters: { //這裏咱們使用es6新語法箭頭函數
arrList: state => state.arr.map(item => item.score >= 60 ? '及格':'不及格')
}
複製代碼
在組件中使用 mapGetters來調取 getters中的數據。
結合 ...對象運算符來合併咱們組件的本地計算屬性。
header.vue:
<template>
<div>
<ul>
<li v-for="item in arrList">{{item}}</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['arrList'])
}
}
</script>
複製代碼
最後若是咱們想給getters屬性起個別名,咱們能夠經過對象的形式:
<template>
<div>
<ul>
<li v-for="item in newArr">{{item}}</li>
</ul>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters({
newArr: 'arrList' //給getters屬性arrList起個別名newArr
})
}
}
</script>
複製代碼