Vuex 核心模塊
state
- 單一狀態樹,用一個對象就包含了全部的應用層級狀態
- mapState 當一個組件需要多個狀態的時候, 將這些狀態都聲明爲計算屬性,會有些重複和冗餘
- 對象展開符號 …mapState({})
import {mapState} from 'vuex'
export default {
// mapState要寫到computed上面 ,用了vuex之後就要把data給忘了.
computed: mapState({
count: state => state.count,
countAlias: "count",
countPlusLocalState(state) {
return state.count + this.localCount
}
})
// ...mapState({count}) 擴展函數符
}
getters
- 從store 中的state中派生出一些狀態
- mapGetters 輔助函數,僅僅是將store中的getters映射到局部計算屬性
- getters (可以認爲是store的計算屬性)
const store = new Vuex.Store({
state: {
todos: [
{id: 1, text: '...', done: true},
{id: 2, text: '...', done: false},
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
// use:
,computed:{
doneTodosCount(){
// this.$store就是vuex 上面的
return this.$store.getters.doneTodos
}
}
// use:
,computed:{
...mapGetters([
'doneTodos'
])
}
mutations
- 更改Vuex的store中的狀態,的唯一方式是提交mutation(不能直接調用句柄,必須通過觸發)
- mutations 就是vue 中的methods
- 每一個mutation都有一個字符串的事件類型(type)和一個回調函數(handler)
- 使用常量代替mutation事件類型
- mutation必須是同步函數
// mutation-type.js
export const SOME_MUTATION='SOME_MUTATION'
// store.js
import {SOME_MUTATION} from './mutation-type'
const store=new Vuex.Store({
state:{...},
mutations:{
// 接受一個常量作爲Objeck對象的key.是es6的寫法
[SOME_MUTATION](state){
//mutate state
}
}
})
然後調用
// use:
import {mapMutations} from 'vuex'
import {SOME_MUTATION} from './mutation-type'
export default {
methods:{
test(){
this.$store.commit(SOME_MUTATION)
},
...mapMutations([
'SOME_MUTATION'
// 映射thisincrement()爲this.$store.commit('SOME_MUTATION')
])
}
}
actions
- action提交的是mutation
- action可以包含任何異步操作
- mapActions輔助函數將組建的methods映射爲store.dispatch調用
- view->store.dispatch(‘increment’)
- action->commit(‘someMutation’)
actions:{
async actionA({commit}){
commit('gotDate',await getDate())
},
async actionB({dispatch,commit}){
await dispatch('actionA')//等待actionA完成
//commit 可以帶數據過去
commit('gotOtherData',await getOtherData())
}
}
// use:
import {mapActions} from 'vuex'
export default {
methods:{
test(){
store.dispatch('actionB')
},
...mapActions([
'actionB'
//映射this.incrment()
// this.$store.dispatch('actionB')
])
}
}
modules
- vuex運行我們將store分割到模塊(module).每個模塊擁有自己的state,mutation,action,getters,甚至是嵌套子模塊–從上至下進行類似的分割
- store創建之後,你可以使用store,registerModule方法註冊模塊
const moduleA={
state:{},
mutations:{},
actions:{},
getters:{}
}
const moduleB={
state:{},
mutations:{},
actions:{},
getters:{}
}
const store=new Vuex.Store({
modules:{
a:moduleA,
b:moduleB
}
})
// use:
store.state.a
store.state.b
附:
//動態註冊一個module
store.registerModule('moduleC',{})
plugins
- vuex的store 接受plugins選項,這個選項暴露出每次mutation的鉤子,vuex插件就是一個函數,他接收sotre作爲唯一參數
- 在插件中不允許直接修改狀態–類似於組建,智能通過提交mutation來觸發變化;
- 自定義的狀態快照
const myPlugin = store => {
// 當store 初始化後調用
store.subscribe((mutation,state)=>{
// 每次mutation之後調用
// mutation的格式爲{type,payload}
})
}
// use
const store=new Vuex.Store({
plugins:[myPlugin]
})
還有啥?
- Vuex的思維處理表單
<input :value="message" @input="updateMessage">
- 測試Action需要增加一個mocking服務層, 測試文件中用mock服務響應API調用,爲例便於解決mock依賴,可以用webpack和inject-loader打包測試文件;
- Hot MOdule Replacement API, Vuex支持在開發過程中熱重載mutation,mudules,actions 和getters.
// 測試Actions 演示
import {expect} from 'chai'
const actionsInjector=require('inject!./actions')
const actions=actionsInjector({
'../api/shop':{
getProducts(cb){
setTimeout(()=>{
cb([/*mocked response*/])
},100)
}
}
})
// 測試代碼
describe('actions',()=>{
it("getAllProducts",done=>{
testAction(actions.getAllProducts,[],{},[
{type:'REQUEST_PRODUCTS'},
{type:'RECEIVE_PRODUCTS',payload:{}}
],done)
})
})
vuex-router-sync
- vue 管理視圖的
- vuex 管理數據元
- vuex-router-sync 是鏈接vuex和vue-router
import {sync} from 'vuex-router-sync'
import store from './vuex/store'
import router from './router'
sync(store,router)
this.$store.state.route.path
this.$store.state.route.params
this.$store.state.route.query