先給出官網地址javascript
官方解釋: Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化html
vuex主要是是作數據交互,父子組件傳值能夠很容易辦到,可是兄弟組件間傳值(兄弟組件下又有父子組件),或者大型spa單頁面框架項目,頁面多而且一層嵌套一層的傳值,異常麻煩,用vuex來維護共有的狀態或數據會顯得駕輕就熟。vue
npm install --save vuex複製代碼
【1】在src文件夾下新增一個store文件夾,裏面添加一個index.js文件java
【2】在main.js文件中引入store文件下的index.jsvuex
// main.js內部對vuex的配置
import store from '@/store/index.js'
new Vue({
el: '#app',
store, // 將store暴露出來
template: '<App></App>',
components: { App }
});
複製代碼
【3】store文件下的index.js配置npm
import Vue from 'vue'; //首先引入vue
import Vuex from 'vuex'; //引入vuex
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// state 相似 data
//這裏面寫入數據
},
getters:{
// getters 相似 computed
// 在這裏面寫個方法
},
mutations:{
// mutations 相似methods
// 寫方法對數據作出更改(同步操做)
},
actions:{
// actions 相似methods
// 寫方法對數據作出更改(異步操做)
}
})複製代碼
在store中定義商品的原價,計算折扣價,根據用戶輸入的數量和商品原價計算出總價app
【1】咱們約定store中的數據是如下形式框架
import Vue from 'vue'; //首先引入vue
import Vuex from 'vuex'; //引入vuex
Vue.use(Vuex)
export default new Vuex.Store({
state: {
price: 100, // 原價
total: '', // 總價
},
getters:{
// 折扣價
discount(state, getters) {
return state.price*0.8
}
},
mutations:{
// 計算總價:第一個參數爲默認參數state, 後面的參數爲頁面操做傳過來的參數
getTotal(state, n) {
return state.total = state.price * n;
}
},
actions:{
// 這裏主要是操做異步操做的,使用起來幾乎和mutations方法如出一轍
// 除了一個是同步操做,一個是異步操做,一個使用commit調用,一個使用dispatch調用
// 這裏就很少介紹了,有興趣的能夠本身去試一試,
// 好比你能夠用setTimeout去嘗試一下
}
})複製代碼
【2】在頁面中使用store中的數據異步
<template> <div> <p>原價:{{price}}</p> <p>8折:{{discount}}</p> <p>數量:<input type="text" v-model="quantity"></p> <p>總價:{{total}}</p> <button @click="getTotal">計算總價</button> </div> </template> <script> export default { data() { return { quantity: 0, } }, computed: { price() { return this.$store.state.price }, discount() { return this.$store.getters.discount }, total() { return this.$store.state.total } }, mounted() { }, methods: { getTotal() { this.$store.commit('getTotal', this.quantity) } }, } </script>複製代碼
【3】頁面效果函數
你能夠向 store.commit 傳入額外的參數,即 mutation 的 載荷(payload)
store.commit('increment', 10)複製代碼
// ...
mutations: {
increment (state, n) {
state.count += n
}
}複製代碼
在大多數狀況下,載荷應該是一個對象,這樣能夠包含多個字段而且記錄的 mutation 會更易讀
store.commit('increment', {
amount: 10
})複製代碼
// ...
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}複製代碼
提交 mutation 的另外一種方式是直接使用包含 type 屬性的對象
store.commit({
type: 'increment',
amount: 10
})複製代碼
// ...
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}複製代碼
【1】mapState
當一個組件須要獲取多個狀態時候,將這些狀態都聲明爲計算屬性會有些重複和冗餘。爲了解決這個問題,咱們可使用mapState輔助函數幫助咱們生成計算屬性,有了對象展開運算符... 咱們能夠將mapState函數與頁面局部的計算屬性混合使用,修改上面的案例以下
import { mapState } from 'vuex'
export default {
computed: {
// 當前頁面的計算屬性
localCoputed() {
return 'test'
},
// 使用對象展開運算符將 state 混入 computed 對象中
...mapState([
'price',
'total'
]),
},複製代碼
若是你想將一個 state屬性另取一個名字,使用對象形式:
...mapState({
goodsPrice: 'price',
priceTotal: 'total'
}),
複製代碼
【2】mapGetters
mapGetters輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性
import { mapState, mapGetters } from 'vuex'
export default {
computed: {
// 當前頁面的計算屬性
localCoputed() {
return 'test'
},
// 使用對象展開運算符將 state 混入computed 對象中
...mapState([
'price',
'total'
]),
// 使用對象展開運算符將 getter 混入 computed 對象中
...mapGetters([
'discount'
]),
},複製代碼
若是你想將一個 getter 屬性另取一個名字,使用對象形式:
...mapGetters({
priceDiscount: 'discount'
}),複製代碼
【3】mapMutations
mapMutations輔助函數將組件中的 methods 映射爲store.commit調用, 修改上面案例
import { mapMutations } from 'vuex'
export default {
methods: {
// 使用對象展開運算符將 mutation 混入 methods 對象中
...mapMutations([
'getTotal',
]),
},複製代碼
若是你想將一個 mutation 另取一個名字,使用對象形式:
...mapMutations({
allTotal: 'getTotal',
}),複製代碼
那麼,問題來了,以前咱們也說過,mutations對象中的方法是能夠傳參的(payload),那麼在mapMutations中如何傳參呢?
其實很簡單:像寫通常的方法同樣,直接在方法名後面的( )中將須要傳遞的參數寫進去
<button @click="getTotal(quantity)">計算總價</button> 複製代碼
...mapMutations([
'getTotal', // 將this.getTotal(quantity)映射爲this.$store.commit('getTotal', quantity)
]),複製代碼
【4】mapActions
使用 mapActions 輔助函數將組件的 methods 映射爲store.dispatch調用
import { mapActions} from 'vuex'
export default {
methods: {
// 使用對象展開運算符將 action 混入 methods 對象中
...mapActions([
'increment', // 將this.increment()映射爲this.$store.dispatch('increment')
]),
},
複製代碼
若是你想將一個 action 另取一個名字,使用對象形式:
...mapActions({
add: 'increment',
}),複製代碼
在項目比較複雜的時候,數據所有寫在一個state 方法所有集中一個mutations中,將會使咱們的文件顯得太過於臃腫,並且不易維護,那怎麼辦呢?仍是那句話辦法總比問題多,vuex爲咱們提供了module這樣一個模塊的概念。咱們能夠利用它來根據咱們個個組件或者頁面所須要的數據一一分割成不一樣的模塊,看下面示例
const moduleA = {
state: {},
mutations: {},
actions: {},
getters: {}
}
const moduleB = {
state: {},
mutations: {},
actions: {},
getters: {}
}
export default new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
})
// 在各自的模塊內部使用
state.price // 這種使用方式和單個使用方式同樣,直接使用就行
//在組件中使用
store.state.a.price // 先找到模塊的名字,再去調用屬性
store.state.b.price // 先找到模塊的名字,再去調用屬性複製代碼