State
1. 前言
本小節(jié)我們將學(xué)習(xí)和使用 Vuex 中 state 的概念。包括如何創(chuàng)建 state、組件中獲取 state、以及輔助函數(shù) mapState 的使用方法。
2. 創(chuàng)建數(shù)據(jù)倉(cāng)庫(kù)
在上一小節(jié)中,我們已經(jīng)給大家寫(xiě)了一個(gè)簡(jiǎn)單的示例,大家一定還記得 Vuex.Store({...})
這個(gè)方法。在 Vuex 中,我們通過(guò)該方法創(chuàng)建一個(gè)數(shù)據(jù)倉(cāng)庫(kù),并把數(shù)據(jù) state 傳入。例如:
const store = new Vuex.Store({
state: {
count: 12000,
name: '慕課網(wǎng)',
logo: ''
}
})
那么,創(chuàng)建完數(shù)據(jù)倉(cāng)庫(kù)后,我們?cè)鯓硬拍茉?Vue 組件中使用它呢?我們知道,要使用 Vue 需要通過(guò) new Vue () 創(chuàng)建一個(gè) Vue 實(shí)例,并傳入對(duì)象的參數(shù)。要在 Vue 中使用 store,只需要在創(chuàng)建 Vue 實(shí)例的時(shí)候?qū)?store 傳入即可:
var vm = new Vue({
el: '#app',
store: store
})
3. 在 Vue 組件中獲得 Vuex 狀態(tài)
那么我們?nèi)绾卧?Vue 組件中展示狀態(tài)呢?由于 Vuex 的狀態(tài)存儲(chǔ)是響應(yīng)式的,從 store 實(shí)例中讀取狀態(tài)最簡(jiǎn)單的方法就是在計(jì)算屬性中返回某個(gè)狀態(tài):
<!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> {{ count }} </div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.1.2/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
count: 12
}
})
var vm = new Vue({
el: '#app',
store,
computed: {
count() {
return this.$store.state.count
}
}
})
</script>
</html>
代碼解釋
JS 代碼第 4-8 行,我們定義了倉(cāng)庫(kù) store。
JS 代碼第 11 行,創(chuàng)建 Vue 實(shí)例的時(shí)候傳入 store。
JS 代碼第 13-15 行,利用計(jì)算屬性返回 count。
HTML 中利用插值顯示 count 的數(shù)據(jù)。
4. mapState 輔助函數(shù)
當(dāng)一個(gè)組件需要獲取多個(gè)狀態(tài)時(shí)候,將這些狀態(tài)都聲明為計(jì)算屬性會(huì)有些重復(fù)和冗余。為了解決這個(gè)問(wèn)題,我們可以使用 mapState 輔助函數(shù)幫助我們生成計(jì)算屬性:
<!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> 我是: {{ name }},我的今年:{{ age }}</div>
<div>{{countPlusAge}}</div>
</div>
</body>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vuex@3.1.2/dist/vuex.js"></script>
<script type="text/javascript">
const store = new Vuex.Store({
state: {
name: '句號(hào)',
age: 18
}
})
var vm = new Vue({
el: '#app',
store,
data() {
return {
count: 1
}
},
computed: Vuex.mapState({
// 箭頭函數(shù)可使代碼更簡(jiǎn)練
name: state => state.name,
// 傳字符串參數(shù) 'age' 等同于 `state => state.age`
age: 'age',
// 為了能夠使用 `this` 獲取局部狀態(tài),必須使用常規(guī)函數(shù)
countPlusAge (state) {
return state.age + this.count
}
})
})
</script>
</html>
代碼解釋
JS 代碼第 4-9 行,我們定義了倉(cāng)庫(kù) store。
JS 代碼第 12 行,創(chuàng)建 Vue 實(shí)例的時(shí)候傳入 store。
JS 代碼第 18-28 行,利用計(jì)算屬性分別返回 name、age、countPlusAge。
當(dāng)映射的計(jì)算屬性的名稱(chēng)與 state 的子節(jié)點(diǎn)名稱(chēng)相同時(shí),我們也可以給 mapState 傳一個(gè)字符串?dāng)?shù)組。
computed: Vuex.mapState([
// 映射 this.age 為 store.state.age
'age',
// 映射 this.name 為 store.state.name
'name'
])
// ===等同于===
computed: Vuex.mapState({age:'age', name: 'name'})
//
5. 對(duì)象展開(kāi)運(yùn)算符
mapState 函數(shù)返回的是一個(gè)對(duì)象。我們?nèi)绾螌⑺c局部計(jì)算屬性混合使用呢?通常,我們需要使用一個(gè)工具函數(shù)將多個(gè)對(duì)象合并為一個(gè),以使我們可以將最終對(duì)象傳給 computed 屬性。但是自從有了對(duì)象展開(kāi)運(yùn)算符,我們可以極大地簡(jiǎn)化寫(xiě)法:
computed: {
localComputed () { /* ... */ },
// 使用對(duì)象展開(kāi)運(yùn)算符將此對(duì)象混入到外部對(duì)象中
...Vuex.mapState({
// ...
})
}
6. 小結(jié)
本節(jié),我們帶大家學(xué)習(xí)了 Vuex 中 state 的使用方式。主要知識(shí)點(diǎn)有以下幾點(diǎn):
- 在 store 中定義 state 數(shù)據(jù)。
- 通過(guò) $store.state 訪問(wèn) state 中的數(shù)據(jù)。
- 使用 mapState 輔助函數(shù)簡(jiǎn)化獲取 state 中數(shù)據(jù)的寫(xiě)法。