Getter
1. 前言
本小節我們將介紹 Vuex 中 getter 的使用方式。包括如何定義 getter、使用 getter、輔助函數 mapGetters 的使用。Getter 在項目中的使用非常普通,學會使用 Getter 可以避免我們重復的通過 state 獲取數據。同學們在學完本小節后可以多嘗試寫一些 Getter 來鞏固本節的知識點。
2. 慕課解釋
Vuex 允許我們在 store 中定義 “getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,而且只有當它的依賴值發生了改變才會被重新計算?!?官方定義
我們可以把 Getter 理解成是封裝好的獲取數據的方法,在方法內部我們可以對 state 中的數據做一些相應的處理,最后返回我們想要的數據。
3. 用法
3.1 通過屬性訪問
Getter 接受 state 作為其第一個參數,我們可以對 state 中的數據做相應的處理,最終返回我們想要的數據:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-for="item in skillList" :key="item.name">{{item.name}}</div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
name: '句號',
age: 18,
skill: [
{name: 'Vue', type: 1},
{name: 'React', type: 1},
{name: 'JAVA', type: 2},
{name: 'Webpack', type: 3},
{name: 'Node', type: 1}
]
},
getters: {
skillList: state => {
return state.skill.filter(item => item.type === 1)
}
}
})
var vm = new Vue({
el: '#app',
store,
computed: {
skillList() {
return this.$store.getters.skillList
}
}
})
</script>
</html>
代碼解釋:
JS 代碼第 16-20 行,我們定義了 Getter 方法 skillList,skillList 內部我們返回狀態 skill 中 type 為 1 的數據。
JS 代碼第 26-28 行,我們通過 $store.getters 獲取 skillList 的返回值。
Getter 也可以接受其他 getter 作為第二個參數:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-for="item in skillList" :key="item.name">{{item.name}}</div>
<div>我有 {{count}} 個技能包</div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
name: '句號',
age: 18,
skill: [
{name: 'Vue', type: 1},
{name: 'React', type: 1},
{name: 'JAVA', type: 2},
{name: 'Webpack', type: 3},
{name: 'Node', type: 1}
]
},
getters: {
skillList: state => {
return state.skill.filter(item => item.type === 1)
},
skillCount: (state, getters) => {
return getters.skillList.length
},
}
})
var vm = new Vue({
el: '#app',
store,
computed: {
skillList() {
return this.$store.getters.skillList
},
count() {
return this.$store.getters.skillCount
}
}
})
</script>
</html>
代碼解釋
JS 代碼第 16-23 行,我們定義了 Getter 方法 skillList 和 skillCount,skillList 內部我們返回 skill 數據 中 type 為 1 的數組,skillCount 內部我們通過 getters 獲取 skillList 的數組長度。
JS 代碼第 28-30 行,我們通過 $store.getters 獲取 skillList 的返回值。
JS 代碼第 31-33 行,我們通過 $store.getters 獲取 skillCount 的返回值。
3.2 通過方法訪問
在上一個例子中我們只能通過 skillList 獲取 type 為 1 的數據列表,那么如果我想獲取 type 為 2 的數據呢?同學們可能會說:我們在定義一個 skillList2 不就好了!確實這樣可以滿足需要,但是,如果又有 type = 3、type = 4 等等其他的呢?難道我們還要繼續寫 skillList3、skillList4 嗎?
其實 getter 除了可以直接返回數據之外,也可以通過讓 getter 返回一個函數,來實現給 getter 傳參。在對 store 里的數組進行查詢時非常有用。
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-for="item in skillList" :key="item.name">{{item.name}}</div>
<div>我有 {{count}} 個技能包</div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
name: '句號',
age: 18,
skill: [
{name: 'Vue', type: 1},
{name: 'React', type: 1},
{name: 'JAVA', type: 2},
{name: 'Webpack', type: 3},
{name: 'Node', type: 1}
]
},
getters: {
skillList: state => (type) => {
return state.skill.filter(item => item.type === type)
},
skillCount: (state, getters) => (type) => {
return getters.skillList(type).length
},
}
})
var vm = new Vue({
el: '#app',
store,
computed: {
skillList() {
return this.$store.getters.skillList(2)
},
count() {
return this.$store.getters.skillCount(2)
}
}
})
</script>
</html>
代碼解釋:
JS 代碼第 17-19 行,我們定義了 Getter 方法 skillList,skillList 返回一個函數,該函數接收一個 type 參數,函數內部返回 state.skill 中對應 type 的數組。
JS 代碼第 20-22 行,我們定義了 Getter 方法 skillCount,skillCount 返回一個函數,該函數接收一個 type 參數,函數內部獲取 getters.skillList 的值,并返回數組長度。
JS 代碼第 28-30 行,我們通過 $store.getters.skillList 傳入參數 type 獲取 skillList 的返回值。
JS 代碼第 31-33 行,我們通過 $store.getters.skillCount 傳入參數 type 獲取 skillCount 的返回值。
4. mapGetters 輔助函數
mapGetters 輔助函數僅僅是將 store 中的 getter 映射到局部計算屬性:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="app">
<div v-for="item in skillList" :key="item.name">{{item.name}}</div>
<div>我有 {{skillCount}} 個技能包</div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
name: '句號',
age: 18,
skill: [
{name: 'Vue', type: 1},
{name: 'React', type: 1},
{name: 'JAVA', type: 2},
{name: 'Webpack', type: 3},
{name: 'Node', type: 1}
]
},
getters: {
skillList: state => {
return state.skill.filter(item => item.type === 1)
},
skillCount: (state, getters) => {
return getters.skillList.length
},
}
})
var vm = new Vue({
el: '#app',
store,
computed: {
...Vuex.mapGetters([
'skillList',
'skillCount'
])
}
})
</script>
</html>
代碼解釋:
JS 代碼第 29-32 行我們通過 Vuex.mapGetters 獲取 skillList 和 skillCount 的值。
如果你想將一個 getter 屬性另取一個名字,可以使用對象形式:
Vuex.mapGetters({
skillListAlias: 'skillList',
skillCountAlias: 'skillCount'
})
5. 小結
本節,我們帶大家學習了 Vuex 中 Getter 的使用方式。主要知識點有以下幾點:
- 在 store 中定義 Getter 數據。
- 通過 $store.getter 訪問 getter。
- 通過讓 getter 返回一個函數給 getter 傳參。
- 使用 mapGetters 輔助函數簡化獲取 getter 的寫法。