vuex
::運用場景:根據專案規模判斷::
不能直接改變store,改變store唯一途徑就是顯示地提交mutations。這樣使得我們可以方便跟蹤每一個狀態的變化,從而讓我們實現一些工具幫助我們更好的瞭解我們的應用
state
單一狀態書,用一個物件就包含了全部的應用層級狀態
- mapState 當一個元件需要獲取多個狀態時候,將這些狀態都宣告為計算屬性會有些重複和冗餘
- 物件展開符號 …mapState({{})
import { mapState } from 'vuex'
dexport default {
computed: mapState({
count: state => state.count,
countAlias: 'count',
countPlusLocalState (state) {
return state.count + this.localCount
}
// ...mapState({count}) 擴充套件函式符
})
}
複製程式碼
getters
從store中的state 中派生出一些狀態
- mapGetters 輔助函式僅僅是將store中的getters對映到區域性計算屬性
- 對state進行擴充套件,通過getters 進行設定 (相當於 computed,可以認為是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)
}
})
複製程式碼
computed: {
doneTodosCount () {
return this.$store.getters.doneTodos
}
}
複製程式碼
computed:{
...mapGetters([
'doneTodosCount'
])
}
複製程式碼
mutations
- 更改Vuex的store中的狀態的唯一方法是提交mutation(不能直接呼叫控制程式碼,必須通過觸發)
- mutations就是vue methods
- 每個mutation都有一個字串的事件型別(type)和一個回撥函式(handler)
- 使用常量替代Mutation事件型別
- mutation必須是同步函式
//mutation-types.js
export const SOME_MUTATION = 'SOME_MUTATION'
//store.js
import { SOME_MUTATION } from './mutation-types'
const store = new Vuex.Store({
state:{...},
mutations:{
[SOME_MUTATION](state){
//mutate state
}
}
})
複製程式碼
Mutations(呼叫篇)
import { mapMutations } from 'vuex'
import { SOME_MUTATION } from './mutation-types'
export default {
methods:{
test(){
this.$store.commit(SOME_MUTATION)
},
...mapMutations([
'SOME_MUTATION'
//對映 this.increment()為this.$store.commit('SOME_MUTATION')
])
}
}
複製程式碼
actions
接受使用者傳過來的event
- 提交的是mutation
- 可以包含任何非同步操作
- mapActions 輔助函式將元件的methods對映為store。dispatch呼叫
- view -> store.dispatch(‘increment’)
- action -> commit(‘someMutation’)
actions:{
async actionA({commit}){
commit('gotData',await getData())
},
async actionB({dispatch,commit}){
await dispatch('actionA') //等待actionA完成
commit('gotOtherData',await getOtherData())
}
}
複製程式碼
Action 呼叫
import { mapActions } from 'vuex'
export default {
methods:{
test(){
store.dispatch('actionB')
}
},
...mapActions([
'actionB'
//對映 this.increment()
//this.$store.dispatch('actionB')
])
}
複製程式碼
modules
- Vuex 執行我們將store分割到模組(module)。 每個模組擁有自己的state、mutation、action、getters甚至巢狀子模組——從上至下進行類似的分割
- store建立之後,你可以使用store.registerModule方法註冊模組
const moduleA = {
state:{...},
mutations:{...},
actions:{...},
getters:{...}
}
const moduleB = {
state:{...},
mutation:{...},
action:{...}
}
複製程式碼
const store = new Vuex.Store({
modules:{
a:moduleA,
b:moduleB
}
})
store.state.a // -> moduleA 的狀態
store.state.b // -> moduleB 的狀態
複製程式碼
store.registerModule('myModule',{
// ...
})
複製程式碼
plugins
- Vuex的store接受plugins選項,這個選項暴露出每次mutation的鉤子。Vuex外掛就是一個函式,它接受sotre作為唯一引數
- 在外掛中不允許直接修改狀態——類似於元件,只能通過提交mutation來觸發變化
- 自定義的狀態快照
//plugins 程式碼演示
const myPlugin = store => {
//當store初始化後呼叫
store.subscribe((mutation, state) => {
//每次 mutation 之後呼叫
// mutation 的格式為 {type, payload }
})
}
複製程式碼
const store = new Vuex.Store({
plugins: [myPlugin]
})
複製程式碼
Vuex 的思維處理表單
<input :value:"message" @input="updateMessage">
- 測試Actions需要增加一個mocking服務層,測試檔案中用mock服務迴應API呼叫。為了便於解決mock依賴,可以用Webpack 和inject-loader打包測試檔案
- Hot Module Replacement API ,Vuex 支援在開發過程中熱過載 mutation、modules、actions、getters
測試Actions 演示
import { expect } from ‘chai'
const actionsInjector = require('inject!./actions')
// 使用mocks建立模組
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
(sync 同步、async非同步) vue 檢視 vuex 資料來源 vue-router 路由 vuex-router-sync 連線vuex\vue-router
檢視層
<div id="app">
<h1>Hello APP</h1>
<p>
<router-link to="/foo">go to foo</router-link>
<router-link to="/bar">go to bar</router-link>
</p>
<router-view></router-view>
</div>
複製程式碼
結合Vuex
import { sync } from 'vuex-router-sync'
import store from './vuex/store'
import router from './router'
sync(store,router)
this.$store.state.route.path //current path (string)
this.$store.state.route.params //current params (object)
this.$store.state.route.query //current query (object)
複製程式碼