狀態管理模式
。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化
。//src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
//變量data
state: {},
//相似於計算屬性computed
getters: {},
//方法methods
mutations: {},
//異步操做
actions: {},
//模塊
modules: {}
});
複製代碼
//src/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 的實例注入全部的子組件
store,
render: h => h(App)
}).$mount('#app')
複製代碼
Vuex 使用單一狀態樹
,即用一個對象就包含了所有的應用層級狀態。至此它便做爲一個「惟一數據源 (SSOT)」而存在。這也意味着,每一個應用將僅僅包含一個 store 實例
。單一狀態樹讓咱們可以直接地定位任一特定的狀態片斷,在調試的過程當中也能輕易地取得整個當前應用狀態的快照。vue
//src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
//變量data
state: {
count: 100,
},
//方法methods
mutations: {},
//異步操做
actions: {},
//模塊
modules: {},
//相似於計算屬性computed
getters: {}
});
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="home">
<!--在此使用$store.state.count使用以前聲明的count-->
count:{{ $store.state.count }}
<br>
<!--在此經過計算屬性doubleCount獲得count-->
doubleCount:{{doubleCount}}
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: "Home",
computed: {
doubleCount(){
return this.$store.state.count * 2
}
},
components: {},
};
</script>
複製代碼
在devtool中能夠查看到在state聲明的count vuex
Vuex 容許咱們在 store 中定義「getter」(能夠認爲是 store 的計算屬性),getter相似於計算屬性, 其返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變纔會被從新計算
。緩存
//src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
//變量data
state: {
count: 100,
people:[
{name:'小A', age:8, address:'北京'},
{name:'小B', age:18, address:'上海'},
{name:'小C', age:28, address:'廣州'}
]
},
//相似於計算屬性computed
getters: {
getPeople:state=>{
return state.people.filter(n=>n.age>10)
}
},
//方法methods
mutations: {},
//異步操做
actions: {},
//模塊
modules: {}
});
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="about">
<h1>{{$store.getters.getPeople}}</h1>
</div>
</template>
複製代碼
//src/store/index.js
getters: {
getPeople:state=>{
return state.people.filter(n=>n.age>10)
},
getPeopleLength:(state,getters)=>{
//直接調用上面的getPeople方法並取得其長度
return getters.getPeople.length
}
}
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="about">
<h1>getPeople:{{$store.getters.getPeople}}</h1>
<h3>getPeopleLength:{{$store.getters.getPeopleLength}}</h3>
</div>
</template>
複製代碼
//src/store/index.js
getters: {
getPeople: (state) => {
return state.people.filter((n) => n.age > 10);
},
getPeopleLength: (state, getters) => {
//直接調用上面的getPeople方法並取得其長度
return getters.getPeople.length;
},
getPeopleByage: (state) => (age) => {
return state.people.find((n) => n.age === age);
},
/*等同於
getPeopleByage:function(state){
return function(age){
return state.people.find(function(n){
return n.age===age
})
}
}*/
}
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="about">
<h1>getPeople:{{$store.getters.getPeople}}</h1>
<h3>getPeopleLength:{{$store.getters.getPeopleLength}}</h3>
<h5>getPeopleByage:{{$store.getters.getPeopleByage(28)}}</h5>
</div>
</template>
複製代碼
更改 Vuex 的 store 中的狀態的惟一方法是提交 mutation
。Vuex 中的 mutation 很是相似於事件:每一個 mutation 都有一個字符串的事件類型 (type) 和 一個回調函數 (handler)。這個回調函數就是咱們實際進行狀態更改的地方,而且它會接受 state 做爲第一個參數bash
雖然直接對state進行更改也能夠獲得一樣的效果,可是devtool沒法監聽到state的變化,這將會給項目的維護帶來困難,因此對狀態更改仍是須要使用commit
方法app
//src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
//變量data
state: {
count: 100,
people: [
{ name: "小A", age: 8, address: "北京" },
{ name: "小B", age: 18, address: "上海" },
{ name: "小C", age: 28, address: "廣州" },
],
},
//相似於計算屬性computed
getters: {
getPeople: (state) => {
return state.people.filter((n) => n.age > 10);
},
getPeopleLength: (state, getters) => {
//直接調用上面的getPeople方法並取得其長度
return getters.getPeople.length;
},
getPeopleByage: (state) => (age) => {
return state.people.find((n) => n.age === age);
},
},
//方法methods
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
}
},
//異步操做
actions: {},
//模塊
modules: {},
});
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="home">
count:{{ $store.state.count }}
<br />
doubleCount:{{ doubleCount }}
<button @click="add">+</button>
<button @click="sub">-</button>
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: "Home",
computed: {
doubleCount() {
return this.$store.state.count * 2;
}
},
methods: {
add(){
this.$store.commit('increment')
},
sub(){
this.$store.commit('decrement')
}
},
components: {},
};
</script>
複製代碼
你能夠向 store.commit 傳入額外的參數,即 mutation 的 載荷(payload)
異步
//src/store/index.js
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
mul(state,payload){
state.count *= payload.amount
}
}
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="home">
count:{{ $store.state.count }}
<br />
doubleCount:{{ doubleCount }}
<button @click="add">+</button>
<button @click="sub">-</button>
<button @click="mul">*10</button>
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: "Home",
computed: {
doubleCount() {
return this.$store.state.count * 2;
},
},
methods: {
add() {
this.$store.commit("increment");
},
sub() {
this.$store.commit("decrement");
},
mul() {
this.$store.commit({
type: "mul",
amount: 10,
});
},
},
components: {},
};
</script>
複製代碼
Action 相似於 mutation,不一樣在於:函數
不是直接變動狀態
。包含任意異步操做
。理解了mutation以後理解action也相對簡單,action用於處理異步操做
,與mutation相比,action經過$store.dispatch('xxx')
觸發而不是store.dispatch => action => $store.commit => mutation`學習
<!--src/views/Home.vue-->
<template>
<div class="home">
count:{{ $store.state.count }}
<br />
doubleCount:{{ doubleCount }}
<button @click="add">+</button>
<button @click="sub">-</button>
<button @click="mul">*10</button>
<button @click="div">/10</button>
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: "Home",
computed: {
doubleCount() {
return this.$store.state.count * 2;
},
},
methods: {
add() {
this.$store.commit("increment");
},
sub() {
this.$store.commit("decrement");
},
mul() {
this.$store.commit({
type: "mul",
amount: 10,
});
},
div() {
this.$store.dispatch("division");
},
},
components: {},
};
</script>
複製代碼
//src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
export default new Vuex.Store({
//變量data
state: {
count: 100,
people: [
{ name: "小A", age: 8, address: "北京" },
{ name: "小B", age: 18, address: "上海" },
{ name: "小C", age: 28, address: "廣州" },
],
},
//相似於計算屬性computed
getters: {
getPeople: (state) => {
return state.people.filter((n) => n.age > 10);
},
getPeopleLength: (state, getters) => {
//直接調用上面的getPeople方法並取得其長度
return getters.getPeople.length;
},
getPeopleByage: (state) => (age) => {
return state.people.find((n) => n.age === age);
},
},
//方法methods
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
mul(state, payload) {
state.count *= payload.amount;
},
div(state, payload) {
state.count /= payload.amount;
},
},
//異步操做
actions: {
division(context) {
context.commit({
type: "div",
amount: 10,
});
},
},
//模塊
modules: {},
});
複製代碼
因爲使用單一狀態樹,應用的全部狀態會集中到一個比較大的對象。當應用變得很是複雜時,store 對象就有可能變得至關臃腫。 爲了解決以上問題,Vuex 容許咱們將 store 分割成模塊(module)。每一個模塊擁有本身的 state、mutation、action、getter、甚至是嵌套子模塊. 要調用定義的模塊內的屬性可以使用$store.state.模塊.屬性ui
//src/store/index.js
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
const moduleA = {
state: {
count: 11111111111111,
},
mutations: {},
actions: {},
getters: {
//對於模塊內部的 getter,根節點狀態會做爲第三個參數暴露出來
sumWithRootCount(state, getters, rootState) {
return state.count + rootState.count;
}
}
};
export default new Vuex.Store({
//變量data
state: {
count: 100,
people: [
{ name: "小A", age: 8, address: "北京" },
{ name: "小B", age: 18, address: "上海" },
{ name: "小C", age: 28, address: "廣州" },
],
},
//相似於計算屬性computed
getters: {
getPeople: (state) => {
return state.people.filter((n) => n.age > 10);
},
getPeopleLength: (state, getters) => {
//直接調用上面的getPeople方法並取得其長度
return getters.getPeople.length;
},
getPeopleByage: (state) => (age) => {
return state.people.find((n) => n.age === age);
},
},
//方法methods
mutations: {
increment(state) {
state.count++;
},
decrement(state) {
state.count--;
},
mul(state, payload) {
state.count *= payload.amount;
},
div(state, payload) {
state.count /= payload.amount;
},
},
//異步操做
actions: {
division(context) {
context.commit({
type: "div",
amount: 10,
});
},
},
//模塊
modules: {
moduleA
},
})
複製代碼
<!--src/views/Home.vue-->
<template>
<div class="home">
count:{{ $store.state.count }}
<br/>
doubleCount:{{ doubleCount }}
<button @click="add">+</button>
<button @click="sub">-</button>
<button @click="mul">*10</button>
<button @click="div">/10</button>
<br>
{{$store.state.moduleA.count}}
{{$store.state.sumWithRootCount}}
</div>
</template>
<script>
// @ is an alias to /src
export default {
name: "Home",
computed: {
doubleCount() {
return this.$store.state.count * 2;
}
},
methods: {
add() {
this.$store.commit("increment");
},
sub() {
this.$store.commit("decrement");
},
mul() {
this.$store.commit({
type: "mul",
amount: 10,
});
},
div() {
this.$store.dispatch("division");
},
},
components: {},
};
</script>
複製代碼
關於Vuex還有一些功能未講述,可進入Vuex官網繼續學習this