Vuex 是什么抠艾?
官方給出的解釋:Vuex 是一個(gè)專為 Vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式。它采用集中式存儲管理應(yīng)用的所有組件的狀態(tài)桨昙,并以相應(yīng)的規(guī)則保證狀態(tài)以一種可預(yù)測的方式發(fā)生變化检号。
相信很多新選手看完這段話有種絕望的感覺。開始我也是這樣的蛙酪,后來我想到了一個(gè)比方齐苛!
比如某年級有5個(gè)小班,每個(gè)小班有25個(gè)同學(xué)桂塞,但是只有一個(gè)老師授課凹蜂,假如5個(gè)小班就對應(yīng)著5個(gè)組件,每個(gè)班的25個(gè)同學(xué)就相當(dāng)于每個(gè)組件中的25條數(shù)據(jù)阁危,這個(gè)老師就相當(dāng)于 vuex 玛痊,老師講的課就相當(dāng)于每一條數(shù)據(jù)。要保證每個(gè)同學(xué)受到同樣的教育狂打,就需要這個(gè)老師把每節(jié)課分別講5遍擂煞,還不能保證每個(gè)班的同學(xué)聽到的效果相同。一段時(shí)間后趴乡,老師覺得這樣特別麻煩還很累对省,就想了一個(gè)辦法蝗拿,找了一個(gè)大教室,把這5個(gè)小班的同學(xué)合并到一起蒿涎,這樣每個(gè)課程只需要講一次就好啦哀托,而且還保證了每個(gè)班的同學(xué)聽到的效果相同。這就是 vuex 的作用劳秋,把各個(gè)組件中用到的數(shù)據(jù)統(tǒng)一管理仓手,同步發(fā)放,省時(shí)省心省力俗批。
那這個(gè) vuex 怎么用呢俗或?讓我們從一個(gè)簡單的 Vue 計(jì)數(shù)應(yīng)用開始
一、基本用法
1. 初始化并創(chuàng)建一個(gè)項(xiàng)目
vue init webpack-simple vuex-demo
cd vuex-demo
npm install
2. 安裝 vuex
npm install vuex -S
3. 在 src 目錄下創(chuàng)建 store.js 文件岁忘,并在 main.js 文件中導(dǎo)入并配置
store.js 中寫入
import Vue from 'vue'
//引入 vuex 并 use
import Vuex from 'vuex'
Vue.use(Vuex)
main.js 文件
import Vue from 'vue'
import App from './App.vue'
import store from './assets/store' //導(dǎo)入 store 對象
new Vue({
//配置 store 選項(xiàng)辛慰,指定為 store 對象,會自動將 store 對象注入到所有子組件中干像,在子組件中通過 this.$store 訪問該 store 對象
store,
el: '#app',
render: h => h(App)
})
4. 編輯 store.js 文件
在應(yīng)用 vuex 之前帅腌,我們還是需要看懂這個(gè)流程圖,其實(shí)很簡單麻汰。
① Vue Components 是我們的 vue 組件速客,組件會觸發(fā)(dispatch)一些事件或動作( Actions);
② 我們在組件中發(fā)出的動作,肯定是想獲取或者改變數(shù)據(jù)的五鲫,但是在 vuex 中溺职,數(shù)據(jù)是集中管理的,我們不能直接去更改數(shù)據(jù),所以會把這個(gè)動作提交(Commit)到 Mutations 中;
③ 然后 Mutations 就去改變(Mutate)State 中的數(shù)據(jù)谤祖;
④ 當(dāng) State 中的數(shù)據(jù)被改變之后烂完,就會重新渲染(Render)到 Vue Components (組件)中去洗显, Vue Components (組件)展示更新后的數(shù)據(jù),完成一個(gè)流程。
Vuex 的 核心 是 Store(倉庫),相當(dāng)于是一個(gè)容器澜躺,一個(gè) Store 實(shí)例中包含以下屬性的方法:
state 定義屬性(狀態(tài) 、數(shù)據(jù))
getters 用來獲取屬性
actions 定義方法(動作)
commit 提交變化抒蚜,修改數(shù)據(jù)的唯一方式就是顯示的提交 mutations
mutations 定義變化掘鄙,處理狀態(tài)(數(shù)據(jù))的改變
mapGetters 用來獲取屬性(數(shù)據(jù))
mapActions 用來獲取方法(動作)
store.js 中寫入
// 定義屬性(數(shù)據(jù))
var state = {
count:6
}
// 創(chuàng)建 store 對象
const store = new Vuex.Store({
state
})
// 導(dǎo)出 store 對象
export default store;
方式1、 在 app.vue 中就能通過 this.$store
訪問該 store 對象 嗡髓,獲取該 count
通铲。
其中需要注意的是
this.$store
中的 store 與 main.js 中配置的 store 相對應(yīng),一定要注意大小寫
<template>
<div id="app">
//把 count 方法直接寫入器贩,可自己執(zhí)行
<h1>{{count}}</h1>
</div>
</template>
<script>
export default {
name: 'app',
computed:{
count(){
//返回獲取到的數(shù)據(jù)
return this.$store.state.count
}
}
}
</script>
執(zhí)行
npm run dev
就能在頁面中看到傳過來的數(shù)據(jù)了
方式2颅夺、vuex 提供的 mapGetters 和 mapActions 來訪問
mapGetters 用來獲取屬性(數(shù)據(jù))
① 在 app.vue 中引入 mapGetters
import {mapGetters} from 'vuex'
② 在 app.vue 文件的計(jì)算屬性中調(diào)用 mapGetters 輔助方法,并傳入一個(gè)數(shù)組蛹稍,在數(shù)組中指定要獲取的屬性 count
<script>
import {mapGetters,mapActions} from 'vuex'
export default {
name: 'app',
computed:mapGetters([
//此處的 count 與以下 store.js 文件中 getters 內(nèi)的 count 相對應(yīng)
'count'
])
}
</script>
③ 在 store.js 中定義 getters 方法并導(dǎo)出
getters 用來獲取屬性
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 定義屬性(數(shù)據(jù))
var state = {
count:6
}
// 定義 getters
var getters={
//需要傳個(gè)形參吧黄,用來獲取 state 屬性
count(state){
return state.count
}
}
// 創(chuàng)建 store 對象
const store = new Vuex.Store({
state,
getters
})
// 導(dǎo)出 store 對象
export default store;
這樣頁面上就會顯示傳過來的數(shù)據(jù)了!接下來我們來通過動作改變獲取到的數(shù)據(jù)
④在 store.js 中定義 actions 和 mutations 方法并導(dǎo)出
actions 定義方法(動作)
commit 提交變化唆姐,修改數(shù)據(jù)的唯一方式就是顯示的提交 mutations
mutations 定義變化拗慨,處理狀態(tài)(數(shù)據(jù))的改變
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 定義屬性(數(shù)據(jù))
var state = {
count:6
}
// 定義 getters
var getters={
count(state){
return state.count
}
}
// 定義 actions ,要執(zhí)行的動作奉芦,如流程的判斷赵抢、異步請求
const actions ={
// ({commit,state}) 這種寫法是 es6 中的對象解構(gòu)
increment({commit,state}){
//提交一個(gè)名為 increment 的變化,名字可自定義声功,可以認(rèn)為是類型名烦却,與下方 mutations 中的 increment 對應(yīng)
//commit 提交變化,修改數(shù)據(jù)的唯一方式就是顯式的提交 mutations
commit('increment')
}
}
// 定義 mutations 先巴,處理狀態(tài)(數(shù)據(jù)) 的改變
const mutations ={
//與上方 commit 中的 ‘increment’ 相對應(yīng)
increment(state){
state.count ++;
}
}
// 創(chuàng)建 store 對象
const store = new Vuex.Store({
state,
getters,
actions,
mutations
})
// 導(dǎo)出 store 對象
export default store;
⑤ 在 app.vue 中引入 mapActions 其爵,并調(diào)用
mapActions 用來獲取方法(動作)
import {mapGetters,mapActions} from 'vuex'
調(diào)用 mapActions 輔助方法,并傳入一個(gè)數(shù)組伸蚯,在數(shù)組中指定要獲取的方法 increment
<template>
<div id="app">
//這個(gè) increment 方法與下面 methods 中的 increment 相對應(yīng)
<button @click="increment">增加</button>
<button>減少</button>
<h1>{{count}}</h1>
</div>
</template>
<script>
import {mapGetters,mapActions} from 'vuex'
export default {
name: 'app',
computed:mapGetters([
'count'
]),
methods:mapActions([
//該 increment 來自 store.js 中導(dǎo)出的 actions 和 mutations 中的 increment
'increment',
])
}
</script>
這樣就能通過 button
來改變獲取到的 count
了摩渺。
現(xiàn)在你可以通過
storel.state
來獲取狀態(tài)對象,以及通過store.commit
方法觸發(fā)狀態(tài)變更注意:我們通過提交
mutation
的方式剂邮,而非直接改變store.state.count
摇幻,是因?yàn)槲覀兿敫鞔_地追蹤到狀態(tài)的變化。
這是通過點(diǎn)擊事件讓 count++
挥萌,不妨自己試著寫一下 count--
吧绰姻!
看起來確實(shí)是挺繞的,需要在理解了原理的情況下瑞眼,再細(xì)細(xì)琢磨龙宏,加深理解。