Vue組件間通訊-Vuex
- 2019 年 10 月 3 日
- 筆記
上回說到Vue組件間通訊,最後留了一個彩蛋~~~Vuex。Vuex是另一種組件通訊的方法,這節來說說Vuex(store倉庫)。
首先Vuex需要安裝,安裝的方式有很多,在這裡就不一一細說了。我是通過npm方式安裝的:
npm install vuex --save
安裝好之後需要再main.js里全局引入:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex)
new Vue({
el:'#app',
store,
components: { App },
template: '<App/>'
})
這樣就完成了Vuex的安裝。接下來就是Vuex的用法了:
Vuex有五個屬性:State、Getter、Mutation、Action、Module。
1. State里放入的是倉庫的數據,類似於js里的data:
import Vue from 'vue' const modules = { state:{ name: '小白' } namespaced: true } export default modules
把Vuex放入src下的store文件里,建一個新的組件modules,然後把他拋出來,被引入所需數據的組件:
<script> import { mapState }from 'vuex' export default { computed:{ // name(){ // return this.$store.state.name // } ...mapState(['name']) }, mounted(){ console.log(this.name) } } </script>
Vuex里的數據需要從計算屬性(computed)里獲取,我寫了兩種我常用的方法,都可以接收到數據,在mounted鉤子里列印出的數據:
2. Getters里放入State里數據的擴展數據,可以把它當作計算屬性。比如State里有一個數組,就可以從Getters里獲取到數組的長度,或是取到對象裡面的屬性,用法和計算屬性類似:
import Vue from ‘vue’ const modules = { state:{ list:[ {id :1,content: '第一條'}, {id :2,content: '第二條'} ] }, getter:{ listLength: (state)=>{return state.list.length} },
namespaced: true
}
export default modules;
我在state里存了一個數組,然後getters計算出state里數組的長度,接下來就是在組件里接收了:
<script> import { mapGetters } from 'Vuex' export default { compoted:{ ...mapGetters(['listLength']) }, mounted(){ console.log(this.listLegth) } } </script>
打開控制台列印出2,就是list數組的長度。
除此之外,getters里可以轉化數據類型,如果介面里數據的數據類型不是我們想要的類型,那就把它放進getters里進行一下轉換,然後再拿到組件里用,例如:
import Vue from 'vue' const modules = { state:{ name: '小黑' }, getters:{ showName(state) =>{ return name==='小白'?true:false } }, namespaced: true } export default modules;
此時name里存放的是一組字元串,在getters里把字元串轉換為布爾類型,這個類型轉換有什麼用呢?往下看:
<html> <div v-if="showName"> {{ name }} </div> </html> <script> import { mapState, mapGetters } from 'vuex' export default{ computed:{ ...mapState(['name']), ...mapGetters(['showName']) } } </script>
可以通過這個布爾型的數據判斷name是否顯示,向上面這種就不會顯示,手動將name的值改為’小白’,name才會顯示出來。
3. Mutations里是保存在倉庫的方法,這裡面的方法只能用來改變state裡面的數據,而且想要改變state里的數據只能用mutations里的方法,並且它裡面的方法只能是同步的:
import Vue from 'vue' const modules = { state:{ name: '小黑' }, mutations:{ changeName(state){ state.name = '小白' } }, namespaced: true } export default modules;
還是那個例子,下面是組件調用方法:
<html> <div> {{ name }} <el-button @click="changeName">改變名字</el-button> </div> </html> <script> import { mapState,mapMutations } from 'vuex' export default { compoted:{ ...mapState(['name']) }, methods:{ ...mapMutations(['changeName']) } } </script>
頁面渲染後為:
點擊按鈕之後為:
組件里的按鈕通過調用Vuex里的mutation方法將Vuex里的state數據改變,只不過mutations方法只能同步的,涉及到介面的就不能在它裡面寫,怎麼辦的?往下看:
4. Actions和mutations一樣都是存放Vuex里的方法,只不過他們有兩個最大的不同:
(1) Actions里可以存放非同步方法,而Mutations只能放同步的;
(2) Actions里的方法不可以更改state里的數據,state里的數據只能在Mutations里更改。
Actions存放的是什麼方法?簡單的說,它可以存放Promise方法,也可以存放async方法,也可以在裡面加定時器,通過不同的狀態執行不同的方法,執行方法可以是Actions里的方法,也可以是Mutations里的方法。
Actions我就不舉例子了,因為大部分都用於axios請求介面,簡單跟大家說說這個東西怎麼使用:
import Vue from 'vue' import request from '@/api/axios' const modules = { state:{ list:[] }, actions:{ getList({ commit }){ // 調用介面方法 request.getList() .then((response)=>{ // commit用來分配mutations方法 commit('getList',response) }) } }, mutations:{ getList(state,response){ state.list = response.data } } }
簡單利用actions非同步方法分配給mutations方法,然後在mutations方法里給state里的數據賦值,取到介面數據。
commit用於分配mutations方法,dispatch用於分配actions方法,都需要傳參進去。
組件調用其實和調用mutations方法類似:
<script> import { mapState,mapActions } from 'vuex' export default { computed:{ ...mapState(['list']) }, mounted(){ this.getList() }, methods:{ ...mapActions(['getList']) } } </script>
這樣就基本完成了vuex傳值。
5. module可以把vuex分為不同的模組,使業務邏輯變得更清晰,更準確。在上面的程式碼里,有const modules,給它不同的名字就是分為不同的模組。不同的module可以存入不同的數據和方法,使用起來非常方便。