Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的全部組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。vue
狀態管理模式 vuex
一個狀態自管理應用包含如下幾個部分:state,驅動應用的數據源;bash
view,以聲明方式將 state 映射到視圖;ui
actions,響應在 view 上的用戶輸入致使的狀態變化。this
當咱們的應用遇到多個組件共享狀態時,單向數據流的簡潔性很容易被破壞:spa
多個視圖依賴於同一狀態。code
不一樣視圖須要變動同一狀態。component
因此狀態管理模式就是把共享的狀態提取出來,在一個全局的地方進行統一管理。無論組件在哪,都能觸發行爲、獲取狀態,提升了代碼維護性。cdn
原理簡單理解 對象
Vuex 實現了一個單向數據流,全局管理 state 狀態樹,組件經過派發 Dispatch 一個 action,action 也是沒法直接修改State的,仍是須要經過 Mutation來修改State的數據。action 進行 commit 並調用 Mutations 方法來更改 state,Mutation同時提供了訂閱者模式供組件調用獲取State數據的更新。最後根據 state 的變化觸發視圖的更新。Vue Components:Vue組件。
dispatch:是惟一能執行action的方法。
actions:由組件 dispatch 觸發。而後由commit()來觸發mutation的調用 , 更新 state。
commit:狀態改變提交操做方法。對mutation進行提交,是惟一能執行mutation的方法。
mutations:狀態改變操做方法,由actions中的commit('mutation 名稱')來觸發。該方法只能進行同步操做,且方法名只能全局惟一。
state:頁面狀態管理容器對象。
實踐 - 城市選擇
實現一個常見的城市選擇頁面。包含首頁和城市選擇頁。
新建一個 IndexPage.vue
// IndexPage.vue
<template>
<div>{{city}}</div>
</template>
<script>
import { mapState} from 'vuex'
export default {
name: "IndexPage",
computed: {
...mapState(['city'])
}
}
</script>
複製代碼
新建一個 CityPage.vue
// CityPage.vue
<template>
<div>
<p>當前城市:{{city}}</p>
<div v-for="item of ['北京','上海','廣州']" :key="item">
<button @click="handleChangeCity(item)"
>{{item}}
</button>
</div>
</div>
</template>
<script>
import { mapState ,mapMutations } from 'vuex'
export default {
name: "CityPage",
computed: {
...mapState(['city'])
},
methods: {
...mapMutations(['changeCity']),
handleChangeCity (city) {
this.changeCity(city)
},
},
}
</script>
複製代碼
在 App.vue 中加入這兩個頁面。
// App.vue
<template>
<div>
<IndexPage/>
-----------
<CityPage/>
</div>
</template>
<script>
import IndexPage from './pages/IndexPage'
import CityPage from './pages/CityPage'
export default {
name: 'App',
components: {
IndexPage,
CityPage
}
}
</script>
複製代碼
接下來重點來了,src 裏 新建一個 store 文件夾 (若是使用腳手架搭建的就已經有這個文件夾了)。
store 文件夾下新建一個 index.js ,別忘了注入到 main.js。
// index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
Vue.use(Vuex)
export default new Vuex.Store({
state,
actions,
mutations
})
複製代碼
新建一個 state.js
// state.js
let defaultCity = '全國'
try {
if (localStorage.city) {
defaultCity = localStorage.city
}
} catch (e) {
}
export default {
city: defaultCity
}
複製代碼
新建一個 actions.js
// actions.js
export default {
changeCity (context, city) {
context.commit('changeCity', city)
}
}
複製代碼
新建一個 mutations.js
// mutations.js
export default {
changeCity (state, city) {
state.city = city
try {
localStorage.city = city
} catch (e) {
}
}
}
複製代碼
完成後以下圖所示。選擇新的城市,首頁和城市選擇頁裏的 city 會同步更新。