vuex
是一個狀態管理工具,類似于redux
.
安裝vuex
npm install vuex --save
-
Vuex 的狀態管理存儲是響應式的:就是當你的組件使用到了 Vuex 的某個狀態,一旦它發生改變了,所有關聯的組件都會自動更新相對應的數據。
- 不能直接修改 Vuex 的狀態:修改 Vuex 的狀態唯一途徑是提交(commit) mutations 來實現修改
如上圖,Vuex為Vue Components建立起了一個完整的生態圈,包括開發中的API調用一環。圍繞這個生態圈,簡要介紹一下各模塊在核心流程中的主要功能:
- Vue Components:Vue組件。HTML頁面上,負責接收用戶操作等交互行為,執行dispatch方法觸發對應action進行回應。
- dispatch:操作行為觸發方法,是唯一能執行action的方法。
- actions:操作行為處理模塊。負責處理Vue Components接收到的所有交互行為。包含同步/異步操作,支持多個同名方法,按照注冊的順序依次觸發。向后臺API請求的操作就在這個模塊中進行,包括觸發其他action以及提交mutation的操作。該模塊提供了Promise的封裝,以支持action的鏈式觸發。
- commit:狀態改變提交操作方法。對mutation進行提交,是唯一能執行mutation的方法。
- mutations:狀態改變操作方法。是Vuex修改state的唯一推薦方法,其他修改方式在嚴格模式下將會報錯。該方法只能進行同步操作,且方法名只能全局唯一。操作之中會有一些hook暴露出來,以進行state的監控等。
- state:頁面狀態管理容器對象。集中存儲Vue components中data對象的零散數據,全局唯一,以進行統一的狀態管理。頁面顯示所需的數據從該對象中進行讀取,利用Vue的細粒度數據響應機制來進行高效的狀態更新。
- getters:state對象讀取方法。圖中沒有單獨列出該模塊,應該被包含在了render中,Vue Components通過該方法讀取全局state對象。
舉例說明:
vuex
在main.js
文件中代碼如下
import Vue from 'vue'
import App from './App.vue'
import 'jquery'
import VRouter from 'vue-router'
//導入vuex
import Vuex from 'vuex'
import Apple from './components/apple.vue'
import Banana from './components/banana.vue'
// 全局使用路由
Vue.use(VRouter)
// 設置全局
Vue.use(Vuex)
// 實例化Vuex
let store = new Vuex.Store({
state: {
totalPrice: 0
},
getters: {
getTotal (state) {
return state.totalPrice
}
},
mutations: {
increment (state, price) {
state.totalPrice += price
},
decrement (state, price) {
state.totalPrice -= price
}
},
// actions是在mutations之前的動作,只能調用mutations,不能調用state
// 其實actions也可以理解為中介
// actions 和 mutations的區別:
// actions: 是異步的操作,再去觸發mutations
// mutations: 是同步的操作
actions: {
increase (context, price) {
context.commit('increment', price)
}
}
})
// 實例化router
let router = new VRouter({
......
})
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,//設置全局
template: '<App/>',
components: { App }
})
在apple.vue
中代碼如下:
<template>
<div class="hello">
<h1>{{msg}}</h1>
<button @click="addOne">add one</button>
<button @click="minusOne">minus one</button>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'I am apple',
price: 5
}
},
methods: {
addOne () {
//使用了vuex的actions
this.$store.dispatch('increase', this.price)
},
minusOne () {
//未使用vuex的actions
this.$store.commit('decrement', this.price)
}
}
}
</script>
在banana.vue
中代碼如下:
<template>
<div class="hello">
<h1>{{msg}}</h1>
<button @click="addOne">add one</button>
<button @click="minusOne">minus one</button>
</div>
</template>
<script>
export default {
data () {
return {
msg: 'I am banana',
price: 15
}
},
methods: {
addOne () {
//未使用vuex的actions
this.$store.commit('increment', this.price)
},
minusOne () {
//未使用vuex的actions
this.$store.commit('decrement', this.price)
}
}
}
</script>
在顯示界面 App.vue
文件中
<template>
<div id="app">

{{ totalPrice }}
<apple></apple>
<banana></banana>
</div>
</template>
<script>
import Apple from './components/apple.vue'
import Banana from './components/banana.vue'
export default {
components: {
Apple,
Banana
},
//計算屬性
computed: {
totalPrice () {
// return this.$store.state.totalPrice
return this.$store.getters.getTotal
}
}
}
</script>