[Vue] Vuex 是什麼? 怎麼用? — Getters (3/5)

itsems
itsems_frontend
Published in
7 min readApr 26, 2020
全系列共五篇:
一、[Vue] Vuex 是什麼? 怎麼用? — State、Mutations (1/5)
二、[Vue] Vuex 是什麼? 怎麼用? — Actions (2/5)
三、[Vue] Vuex 是什麼? 怎麼用? — Getters (3/5)
四、[Vue] Vuex 是什麼? 怎麼用? — Modules (4/5)
五、[Vue] Vuex 是什麼? 怎麼用? — 統整、專案結構(5/5)

一句話完結:

Getters 就是 store 裡面的 computed

好啦不可以QQ

Outline:
1. Getters 情境範例
2. Getters 可帶參數

Getters 情境範例

Getters 簡單說就是可以把 state 處理過後再丟出去的人,接續上中篇的範例假設情境:

我想要在頁面上 show 出 5 個 random 的人,還要計算出有幾個是女生

在沒有 getters 的時候,我們需要在 template 處理抓回來的 state ,才能達到這件事情,先在 store.js 裡面加上一個 mutations 把 api 抓回來的值丟進 state 裡面:

接著在 template 上面加上一個顯示女性人數的人數:

<p>Female number: {{FemaleNum}}</p>

然後在 computed 裡面我要加上一個計算出人數的算式:

computed: {
...mapState(["Loaded", "clickedTimes", "users"]),
FemaleNum() {
return this.users.filter(item => item.gender == "female").length;
}

},

就可以在這邊算出每次 random 出的五個人有幾個是女性,但是如果我有很多個地方都需要這個計算,可以乾脆在 store 裡面寫好,在 component 直接取出來用就好了

回來剛剛的 store.js,加上我們的 getters:

getters:
{
FemaleNum(state) {
return state.users.filter(item => item.gender == 'female').length;
}
},

其實就是把剛剛的 computed 拿來用,只是要注意在這邊不是 this,是 state

getters 寫好之後就可以去 App.vue 把剛剛的 computed 替換掉:

computed: {
...mapState(["Loaded", "clickedTimes", "users"]),
...mapGetters(["FemaleNum"])
},

getters 一樣有 mapGetters 可以使用,這樣子就可以了

Getters 可帶參數

getters 除了帶入 state 之外,總共可以帶入三種參數:

  1. state
  2. 其他 getters
  3. 函式

剛剛計算女生人數的 getters 就只有帶入 state,如果要帶入其他 getters 的話,就來新增一個情境:

除了知道抓到的女性人數,還想要知道男性的人數

先在 store 新增一個計算男性人數的 getters,我們可以用整個 users 的陣列長度減掉女性人數就好了:

MaleNum(state, getters) {
return state.users.length - getters.FemaleNum
}

這裡帶入的第二個參數就是 getters,可以直接引用上面寫好的 getters

回到 template 上,來驗證一下寫得對不對,在剛剛的女性人數下面加上一個男性人數,兩個相加等於 5 就對了:

<p>Female number: {{FemaleNum}}</p>
<p>Male numner: {{MaleNum}}</p>

computed 裡面的 mapGetters 也加上剛剛寫好的 MaleNum :

...mapGetters(["FemaleNum", "MaleNum"])

就可以看到結果應該是沒有問題的了:

想要回傳一個函式的話,可以來試著再新增一個情境:

我想要知道抓到的五個人裡面,女生或是男生是不是有超過兩個人

在 store.js 中,加上一個回傳函式的 getters:

returnFn(state) {
return function DetectGender(gd) {
if (state.users.filter(item => item.gender == gd).length > 2)
console.log('There are over 2 ' + gd + ' in data')
else
console.log('No over 2 ' + gd + ' in data');
}
}

因為只有一個參數,也沒有 this,一樣可以簡化為箭頭函式 (ES6):

returnFn: state => gd => {
if (state.users.filter(item => item.gender == gd).length > 2)
console.log('There are over 2 ' + gd + ' in data')
else
console.log('No over 2 ' + gd + ' in data');
}

getters 的參數一定要帶 state,裡面就可以寫入要回傳的函式了,這邊的參數會帶入要偵測的性別是什麼,超過兩個人的話 console 會回覆

接著來 app.vue 加上這個新寫的 getters,先在 template 裡面新增兩個按鈕,來偵測女生或是男生:

// 資料中有沒有超過兩個女生?
<label>Are there more than 2 women in data?</label>
<button @click="DetectGender('female')">Detect</button>
<br />
// 資料中有沒有超過兩個男生?
<label>Are there more than 2 men in data?</label>
<button @click="DetectGender('male')">Detect</button>

然後在 computed 的 mapGetters 加上剛剛的 getteers returnFn ,並在 methods 裡面寫上 template 上面綁 click 的 DetectGender ,把參數帶進去 getters:

methods: {
DetectGender(gd) {
this.returnFn(gd);
},
}

就完成啦:

--

--

itsems
itsems_frontend

Stay Close to Anything that Makes You Glad You are Alive.