"Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化"。這句話是擷取vuex官網上對vuex介紹的一句話,對於很多新手朋友,剛接觸vuex的時候,肯定被它這麼多的專業詞彙搞得一臉懵逼,不知所云。那麼作為新手該如何學習vuex呢,我的建議就是“理解”,用通俗易懂的話和比喻來說明vuex是個幹啥的,是個什麼東西。
vuex
上面的前言,說了要用通俗易懂的話來介紹vuex,那麼該怎麼理解呢?我的理解就是,你把vuex當成一個專案頂層的全域性物件來看待,有了這樣的認識,你在學習vuex肯定會事半功倍的。
安裝vuex
首先我們要安裝:
`
npm install vuex --save
複製程式碼
`
其次就是建立vuex,建立這一塊建議大家按照官方的文件命名來,這樣做的目的嗎,顯而易見,大家都知道開發當中有一些潛在的規範,遵守這些規範就是為了讓大家好理解,我這裡是幹嘛的。在這裡我就建議大家在專案裡單獨建立一個store
的資料夾,並在裡面建立一個index.js
的檔案吧,然後在index.js
裡引入vuex:
`
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(vuex);
// 這個是store資料夾下的index.js檔案
export default new Vuex.Store({ // 匯出這個物件
state: {
},
getters: {
},
mutations: {
},
actions: {
}
})
複製程式碼
`
最後在main.js
的檔案裡引入我們剛建立的store
資料夾裡的index.js
檔案:
`
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store/index'; // 引入vuex
new Vue({
el: '#app',
router,
store, // 注入vuex
components: { App },
template: '<App/>'
})
複製程式碼
`
到這一步,我們的vuex就算是搭建完畢了,下面我們就針對vuex裡的各個功能模組進行探討,vuex下面有四個功能模組state, getters, mutations, actions
,也就是四個子物件。
State
前面我們說了vuex其實就是一個全域性物件,而這個物件呢包含有四個子物件,子物件一:state
,state
是幹嘛的呢?,state
就是這個全域性物件專門用來儲存資料的地方,也就是公共的資料來源:
`
export default new Vuex.Store({
state: { // 這裡是儲存資料的地方,公共的資料來源
animals: [{num: 1, animal: '老虎'}, {num: 2, animal: '獅子'},
{num: 3, animal: '大象'}]
}
})
複製程式碼
`
那麼如何使用這個資料呢?使用很簡單,直接在vue裡的computed
物件裡書寫即可:
`
// 組建裡呼叫
<template>
<div>
<ul>
<li v-for="(item,index) in animals" :key="index">
<label>{{item.num}}</label>
<span>{{item.animal}}</span>
</li>
</ul>
</div>
</template>
// ...其他程式碼省略
computed: {
animals () {
return this.$store.state.animals;
}
}
複製程式碼
`
注意:this.$store
就是我們整個vuex例項,也就是我們說的那個全域性物件,state
就是儲存公共資料的容器。
這樣我們就成功的使用到了vuex state
裡的資料了。
Getter
子物件二:getter
,它的功能和作用就類似於vue裡的computed
,也就是說vuex裡的計算屬性,vue裡的computed
是用來對資料進行額外操作的,vuex裡的getter
也是一樣的:
`
export default new Vuex.Store({
state: { // 這裡是儲存資料的地方,公共的資料來源
animals: [{num: 1, animal: '老虎'}, {num: 2, animal: '獅子'},
{num: 3, animal: '大象'}]
},
getter: {
filterAnimal: state => { // 這是個方法
return state.animals.filter(item => {
return item.num > 1
})
}
}
})
複製程式碼
`
注意:getter
裡面filterAnimal
是個方法,方法名字隨你自己定義,state
這個引數就是vuex儲存資料裡的state
,getter
裡所有的方法都預設傳入了該引數。
使用也是直接在vue裡的computed
物件裡書寫:
`
// 組建裡呼叫
<template>
<div>
<ul>
<li v-for="(item,index) in filterAnimal" :key="index">
<label>{{item.num}}</label>
<span>{{item.animal}}</span>
</li>
</ul>
</div>
</template>
// ...其他程式碼省略
computed: {
filterAnimal () {
return this.$store.getters.filterAnimal;
}
}
複製程式碼
`
Mutations
子物件三:mutations
,官網裡是這樣介紹的:“更改 Vuex 的 store 中的狀態的 唯一 方法是提交 mutation
”,在這段話裡面請大家注意那個“唯一”。這也就是說,對vuexstate
裡面的資料,你要想進行修改,必須通過mutations
方式才可以,只有mutations
這個物件裡的方法才可以修改state
裡的資料,也就是狀態:
`
export default new Vuex.Store({
state: { // 這裡是儲存資料的地方,公共的資料來源
animals: [{num: 1, animal: '老虎'}, {num: 2, animal: '獅子'},
{num: 3, animal: '大象'}]
},
mutations: {
addAnimal (state, params) { // params是來自你呼叫這個方法時傳入的引數
state.animals.push(params)
}
}
})
複製程式碼
`
注意:mutations
裡定義的方法可以接收兩個引數,state
就是資料物件,params
就是呼叫時傳遞過來的資料
組建裡呼叫mutations
裡的方法,使用this.$store.commit()
觸發,引數一是你要觸發的mutations
裡的哪個方法,引數二就是你要傳遞過去的資料:
`
// 組建裡呼叫
<template>
<div>
<button @click="addAnimal()">增加動物</button>
<ul>
<li v-for="(item,index) in filterAnimal" :key="index">
<label>{{item.num}}</label>
<span>{{item.animal}}</span>
</li>
</ul>
</div>
</template>
// ...其他程式碼省略
methods: {
addAnimal () {
let animal = {num: 4, animal: '熊貓'}
this.$store.commit('addAnimal', animal);
}
}
複製程式碼
`
mutations
操作注意事項:mutations
屬於同步操作,所以你在操作時請記得提前宣告好你要操作的資料,也就是state
裡的資料。
Actions
子物件四:actions
類似於mutations
,actions
的不同點有兩點:
action
提交的是mutation
,而不是直接變更狀態;action
可以包含任意非同步操作;
大家請記住上面這兩點,上面介紹mutations
時說過,要想改變state
裡面的資料,唯一的方法就是通過mutations
,所以action
這裡也是通過mutation
:
`
export default new Vuex.Store({
state: { // 這裡是儲存資料的地方,公共的資料來源
animals: []
},
mutations: {
initAnimal (state, params) { // 初始化state裡animals資料
state.animals = params;
}
},
actions: {
initAnimals (context) {
return new Promise((resolve, reject) => {
let animals = [{num: 1, animal: '老虎'}, {num: 2, animal: '獅子'},
{num: 3, animal: '大象'}]
context.commit('initAnimal', animals); //呼叫mutations裡的方法
resolve(animals);
})
}
}
})
複製程式碼
`
組建裡面呼叫,使用vuex裡的this.$store.dispatch()
方法執行,上面例子中的Promise
並沒有實際意義,只是為了演示特意寫出來的,你方法體裡直接寫context.commit()
也是可以的:
`
// 組建裡呼叫
// ...其他程式碼省略
created() {
this.$store.dispatch('initAnimals');
}
複製程式碼
` 在本示例中,呼叫是在組建生命週期鉤子函式裡呼叫,具體在什麼地方呼叫,根據實際的業務需求去實現即可。
mapState、mapGetters、mapActions
mapState、mapGetters、mapActions
這三個是vuex裡簡化呼叫而提供的方法,你如果需要使用,需要在你使用的組建單獨引入這三個方法:
`
// 組建裡呼叫
<template>
<div>
<ul>
<li v-for="(item,index) in animals" :key="index">
<label>{{item.num}}</label>
<span>{{item.animal}}</span>
</li>
</ul>
</div>
</template>
// ...其他程式碼省略
import {mapState, mapGetters, mapActions} from 'vuex';
computed: {
// 使用擴充套件運算子
...mapState({
animals:state => state.animals
}),
}
複製程式碼
`
這裡暫且只示例mapState
了,其他留給大家自己嘗試,稍微說明應用的地方,mapGetters
一般也是在computed
裡呼叫,mapActions
一般是在methods
的方法裡呼叫。
Module
看完上面的內容,其實大家已經會使用vuex了,那麼這個Module
是幹嘛的呢,上面我們說過,vuex是老頂層的全域性物件,如果所有的資料狀態如果都寫在這個index的檔案裡面,程式碼體會越來越大,所以,vuex允許我們把store
分割成各自獨立的模組,每個獨立模組都有自己的state, getters, mutations, actions
,注意哦,分割出去的各個模組,他們的state
裡的資料都是獨立,各自是各自的。:
`
import Vue from 'vue';
import Vuex from 'vuex';
import module1 from './modules/module1';
import module2 from './modules/module2';
// 這個是vuex的主模組,也就是index.js這個檔案
export default new Vuex.Store({
state,
mutations,
actions,
modules: {
module1,
module2
}
複製程式碼
}) `
獨立出去的模組使用import
引入進來,在主模組裡在modules
裡注入即可。
總結
在本篇文章的思路里,是以全域性物件的思維方式來學習vuex,其目的也是為了讓大家更快速的理解和認識vuex,那麼vuex是否就是全域性物件呢,在vuex的官方文件裡就已經給出了答案和解釋:
- Vuex 的狀態儲存是響應式的。當 Vue 元件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的元件也會相應地得到高效更新。
- 你不能直接改變 store 中的狀態。改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣使得我們可以方便地跟蹤每一個狀態的變化,從而讓我們能夠實現一些工具幫助我們更好地瞭解我們的應用。
vuex的主要應用就是對多組建或者多頁面使用同一個資料來源,也就是說共用同一個資料,當我們在某一個組建改變這個資料的某一個狀態或者值時,相應的也讓其他組建和頁面發生相同的變化。 最後也把vuex官網的連結貼在這裡,大家看完後可以在去官網檢視實際API。