Vuex全局的狀態統一管理,解決組件之間狀態共享和數據通訊的問題。vue
store.jsvuex
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex) // 使用插件
// 導出store實例
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
複製代碼
main.js緩存
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store, // 增長store屬性,值是導出store的實例
render: h => h(App)
}).$mount('#app')
複製代碼
經過上面兩個步驟,每一個組件中都有了$store
屬性,就是咱們建立的容器。裏面有commit
,dispatch
,state
,getters
,actions
,mutations
,在每一個組件中能夠經過this.$store
打印出來看看。app
定義狀態異步
export default new Vuex.Store({
state: {
count: 1 // state中定義響應式的數據
}
})
複製代碼
使用狀態:在store的state
中定義的狀態count
,在組件中能夠使用this.$store.state.count
獲取。async
定義mutations函數
在store的mutations
中添加對應的方法this
export default new Vuex.Store({
state: {
count: 1 // state中定義響應式的數據
},
mutations: {
addTen (state, num) {
state.count = state.count + num
}
},
actions: {
}
})
複製代碼
提交mutations 組件中經過commit
提交mutations
去修改state
中的狀態spa
this.$store.commit('addTen', 10)
複製代碼
定義actions 在store的actions
中添加對應的方法插件
export default new Vuex.Store({
state: {
count: 1
},
mutations: {
addTen (state, num) {
// 第一個參數是狀態,第二個是傳入的參數
state.count = state.count + num
}
},
actions: {
minusTen ({commit}, num) {
// 第一個參數是store實例,第二個是傳入的參數
setTimeout(() => {
commit('addTen', num)
}, 1000)
}
}
})
複製代碼
派發動做 組件中能夠使用dispatch
派發一個動做,來觸發actions
中的方法,actions
能夠異步的提交mutations
去修改state
中的狀態
this.$store.dispatch('minusTen', 10)
複製代碼
actions
主要是複用,封裝代碼,處理異步,請求接口等等,真正修改狀態放到了mutations
中處理
定義getters 在store的getters
中添加對應的方法
export default new Vuex.Store({
state: {
count: 1,
person: {
name: '張三'
}
},
getters: {
getName (state) {
// getters是同步的
return state.person.name
}
}
})
複製代碼
使用getters
this.$store.getters.getName
複製代碼
getters
定義的方法至關於計算屬性,至關於定義在computed
同樣,有緩存,依賴改變會從新計算。
組件代碼演示
<template>
<div class="hello">
<h1>{{ this.$store.state.count }}</h1>
<h1>{{ this.$store.getters.getName }}</h1>
<button @click="syncAdd">同步加10</button>
<button @click="asyncAdd">異步加10</button>
</div>
</template>
<script>
export default {
methods: {
syncAdd () {
this.$store.commit('addTen', 10)
},
asyncAdd () {
this.$store.dispatch('minusTen', 10)
}
}
}
</script>
複製代碼
上面的寫法都是在this.$store
中獲取屬性或方法進行操做。
this.$store.state.count
this.$store.getters.getName
this.$store.commit('addTen', 10)
this.$store.dispatch('minusTen', 10)
複製代碼
可是這些操做寫起來比較繁瑣,每次都要寫this.$store
,爲了簡寫,因此vuex提供了一些映射的方法,直接導入到組件中就能夠使用了。
<template>
<div class="hello">
<h1>{{ count }}</h1>
<h1>{{ getName }}</h1>
<button @click="syncAdd">同步加10</button>
<button @click="asyncAdd">異步加10</button>
</div>
</template>
<script>
import {mapActions, mapState, mapMutations, mapGetters} from 'vuex'
export default {
computed: {
...mapState(['count']),
...mapGetters(['getName'])
},
methods: {
syncAdd () {
this.addTen(10)
},
asyncAdd () {
this.minusTen(10)
},
...mapActions(['minusTen']),
...mapMutations(['addTen'])
}
}
</script>
複製代碼
有一點須要說明的是,使用擴展運算符,表示這些方法返回的都是對象,mapState
和mapGetters
須要定義在計算屬性中,由於他們定義的數據是響應式的。而mapActions
和mapMutations
須要定義在methods中。
狀態是能夠分層的,當一個項目維護的狀態太多,能夠拆分紅單獨的模塊,在定義store中有個modules
屬性,裏面能夠定義單獨的模塊。
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
'page1': {
namespaced: true,
state: {
count: 1,
person: {
name: '張三'
}
},
mutations: {
addTen (state, num) {
state.count = state.count + num
}
},
actions: {
minusTen ({commit}) {
setTimeout(() => {
commit('addTen', 10)
}, 1000)
}
},
getters: {
getName (state) {
return state.person.name
}
}
}
}
})
複製代碼
在組件中這樣用
<template>
<div class="hello">
<h1>{{ count }}</h1>
<h1>{{ getName }}</h1>
<button @click="syncAdd">同步加10</button>
<button @click="asyncAdd">異步加10</button>
</div>
</template>
<script>
import {mapActions, mapState, mapMutations, mapGetters} from 'vuex'
export default {
computed: {
...mapState('page1', ['count']),
...mapGetters('page1', ['getName'])
},
methods: {
syncAdd () {
this.addTen(10)
},
asyncAdd () {
this.minusTen(10)
},
...mapActions('page1', ['minusTen']),
...mapMutations('page1', ['addTen'])
}
}
</script>
複製代碼
每一個方法都傳了兩個參數,第一個參數指定命名空間,第二個參數是對應的屬性,爲了進一步簡寫,能夠經過幫助函數指定命名空間,指定當前組件在使用的模塊。
<template>
<div class="hello">
<h1>{{ count }}</h1>
<h1>{{ getName }}</h1>
<button @click="syncAdd">同步加10</button>
<button @click="asyncAdd">異步加10</button>
</div>
</template>
<script>
import { createNamespacedHelpers } from 'vuex'
// 建立幫助函數指定命令空間
let { mapActions, mapState, mapMutations, mapGetters } = createNamespacedHelpers('page1')
export default {
computed: {
...mapState(['count']),
...mapGetters(['getName'])
},
methods: {
syncAdd () {
this.addTen(10)
},
asyncAdd () {
this.minusTen(10)
},
...mapActions(['minusTen']),
...mapMutations(['addTen'])
}
}
</script>
複製代碼
不使用簡寫
this.$store.getters['page1/getName']
this.$store.state.page1.count
this.$store.commit('page1/addTen', 10)
this.$store.dispatch('page1/minusTen', 10)
複製代碼