一、vuex介紹 目標 什麼是Vuex 為什麼學習Vuex 通信方案 | 組件關係 | 數據通信 | | | | | 父子關係 | 父傳子:props ; 子傳父:$emit | | 非父子關係 | vuex (一種組件通信方案) | Vuex是什麼 概念:專門在 Vue 中實現集中式狀態(數據)管 ...
一、vuex介紹
目標
- 什麼是Vuex
- 為什麼學習Vuex
通信方案
組件關係 | 數據通信 |
---|---|
父子關係 | 父傳子:props ; 子傳父:$emit |
非父子關係 | vuex (一種組件通信方案) |
Vuex是什麼
-
概念:專門在 Vue 中實現集中式狀態(數據)管理的一個 Vue 插件,對 vue 應 用中多個組件的共用狀態進行集中式的管理(讀/寫),也是一種組件間通信的方 式,且適用於任意組件間通信。
-
Vuex 實現了一個單向數據流,在全局擁有一個 State 存放數據,當組件要更改 State 中的數據時,必須通過 Mutation 提交修改信息, Mutation 同時提供了訂閱者模式供外部插件調用獲取 State 數據的更新。而當所有非同步操作(常見於調用後端介面非同步獲取更新數據)或批量的同步操作需要走 Action ,但 Action 也是無法直接修改 State 的,還是需要通過Mutation 來修改State的數據。最後,根據 State 的變化,渲染到視圖上。
- Vuex 的狀態存儲是響應式的。當 Vue 組件從 store 中讀取狀態的時候,若 store 中的狀態發生變化,那麼相應的組件也會相應地得到高效更新。
- 改變 store 中的狀態的唯一途徑就是顯式地提交 (commit) mutation。這樣可以方便地跟蹤每一個狀態的變化。
-
原理如圖所示:
vuex為何學
程式頁面多, 數據變數多
- 不同組件數據保持同步
- 數據的修改都是可追蹤
一個戶外商店有兩名員工,張三和李四
一天的早上,他們分別對帳篷的數量做了一次盤點,發現一共有三個帳篷
張三賣出去倆個,他以為庫存里還有一個
李四賣出去一個,他以為庫存里還有兩個
而事實上是,庫存現在已經為零
如果他們再接受客戶的預訂,就會出現庫存不足的情況
張三和李四因為沒有保持庫存的數量的同步導致了尷尬,這個就是所謂的
數據保持同步
店長需要知道, 誰賣出了多少個帳篷,這個行為我們稱之為
數據修改是可追蹤的
圖示:
Vuex中存什麼
多個組件共用狀態,才存儲在Vuex中
某個組件中的私有數據,依舊存儲在data中
例如:
-
登陸的用戶名需要在首頁, 個人中心, 結算頁面使用, 用戶名存在Vuex中
-
文章詳情數據, 只有在文章詳情頁查看, 在自身data中聲明
小結
- 什麼是Vuex
- Vuex是Vue官方推薦的集中式狀態管理機制
- 為何學Vuex
- 數據同步, 集中管理
- Vuex中存什麼
- 多個組件共用的值
二、Vuex學習內容
目標
- 知道Vuex要學習什麼
核心概念
-
安裝(固定)
-
配置項(固定)
配置項 含義 註意 state 單一狀態樹 類似data mutations 數據管家(同步) 唯一修改state地方 actions 非同步請求 要改state需要提交給mutations getters vuex計算屬性 類似computed modules 模塊拆分
圖示關係
單一定義store對象, 裡面5個配置項, 在任意組件可以使用
小結
- Vuex五個核心概念是?
- state / mutations / actions / getters / modules
三、Vuex例子準備
目標
-
創建項目, 為學習準備
-
需求1: App.vue(作為根組件)
-
需求2: 子組件Add和子組件Sub, 嵌入在App.vue里
-
需求3: 三個組件共用庫存數據(保持同步)
-
工程準備
-
初始化新的工程 vuex-demo
vue create vuex-demo
-
清空歡迎界面
-
並設置如下三個組件, 目錄如下:
|-components |---AddItem.vue |---SubItem.vue |-App.vue
App.vue
複製標簽和樣式, 引入AddItem和SubItem2個子組件顯示
<template>
<div id="app">
<h1>根組件</h1>
<span>庫存總數:</span>
<input type="text">
<div style="border:1px solid black; width: 300px;">
<AddItem></AddItem>
</div>
<hr>
<div style="border:1px solid black; width: 300px;">
<SubItem></SubItem>
</div>
</div>
</template>
<script>
import AddItem from '@/components/AddItem'
import SubItem from '@/components/SubItem'
export default {
components: {
AddItem,
SubItem
}
}
</script>
<style>
#app {
width: 300px;
margin: 20px auto;
border:1px solid #ccc;
padding:4px;
}
</style>
AddItem.vue
<template>
<div>
<h3>AddItem組件</h3>
<p>已知庫存數: 0</p>
<button>庫存+1</button>
</div>
</template>
<script>
export default {
}
</script>
SubItem.vue
<template>
<div>
<h3>SubItem組件</h3>
<p>已知庫存數: 0</p>
<button>庫存-1</button>
</div>
</template>
<script>
export default {
}
</script>
小結
- App下套用了AddItem和SubItem, 要在3個組件共用一個數據
四、vuex-store準備
目標
- 創建store倉庫
- 註入到Vue項目中
store概念
每個 Vuex 應用的核心 store(倉庫), 包含5個核心概念
Vuex目錄
和路由模塊router/index.js - 類似, 維護項目目錄的整潔,新建src/store/index.js文件
當然, 這個步驟並不是必需的
使用步驟
-
工程中 - 下載vuex
yarn add vuex
-
store/index.js - 創建定義導出store對象
// 目標: 創建store倉庫對象 // 1. 下載vuex: 終端命令(yarn add vuex) // 2. 引入vuex import Vue from 'vue' import Vuex from 'vuex' // 3. 註冊 Vue.use(Vuex) // 4. 實例化store對象 const store = new Vuex.Store({}) // 5. 導出store對象 export default store
-
main.js - 導入註入到Vue中
import Vue from 'vue' import App from './App.vue' import store from '@/store' // 導入store對象 Vue.config.productionTip = false new Vue({ // 6. 註入到Vue實例中(確保組件this.$store使用) // this.$store = store store, render: h => h(App), }).$mount('#app')
請再次回憶一下vue-router的用法,是不是很像?
小結
-
vuex的核心是什麼?
- store對象(包含5個核心屬性)
-
如何創建store對象?
- 工程下載vuex模塊
- store/index.js
- 引入註冊
- 生成store對象導出
- main.js - 導入註入
五、vuex-state數據源
目標
- 定義state
- 直接使用state
- 輔助函數mapState
state是唯一的公共數據源,統一存儲
定義state
在store/index.js定義state
語法:
/*
const store = new Vuex.Store({
state: {
變數名: 初始值
}
})
*/
具體代碼:
const store = new Vuex.Store({
state: {
count: 100 // 庫存
}
})
使用state2種方式
-
方式1: 組件內 - 直接使用
語法:
this.$store.state.變數名
-
方式2: 組件內 - 映射使用 (推薦)
語法:
// 1. 拿到mapState輔助函數 import { mapState } from 'vuex' export default { computed: { // 2. 把state里變數映射到計算屬性中 ...mapState(['state里的變數名']) } }
AddItem直接用
<template>
<div>
<h3>AddItem組件</h3>
<p>已知庫存數: {{ $store.state.count }}</p>
<button>庫存+1</button>
</div>
</template>
App.vue直接用
計算屬性count, 和輸入框的v-model雙向綁定
<input type="text" v-model="count">
<script>
export default {
computed: {
count: {
set(){},
get(){
return this.$store.state.count
}
}
}
}
</script>
SubItem映射用
<template>
<div>
<h3>SubItem組件</h3>
<p>已知庫存數: {{ count }}</p>
<button>庫存-1</button>
</div>
</template>
<script>
// 需求1: 映射state到計算屬性
// 1. 拿到輔助函數 mapState
// 2. 在computed內, ...mapState(['state變數名'])
// 3. 當計算屬性使用
import { mapState } from 'vuex'
// let r = mapState(['count']) // 提取store里的state叫count的變數
// console.log(r); // 返回值: {count: 函數體(return state里count的值)}
export default {
computed: {
// 映射count, 得到對象展開, 合併到計算屬性中
...mapState(['count'])
},
}
</script>
整個過程的示意圖如下
註意
state是響應式的, 只要state值變化, 頁面上使用的地方會自動更新同步
小結
-
state作用?
定義全局狀態數據源
-
state如何定義?
在store內, state: {變數名: 初始值}
-
state的值如何用到具體vue組件內?
- 直接使用 this.$store.state.變數名
- 映射使用 ...mapState(['state的變數名'])
六、vuex-mutations定義-同步修改
目標
- 定義mutations
定義mutations
mutations類似數據管家, 操作state里的數據
在store/index.js定義mutations
語法:
/*
const store = new Vuex.Store({
mutations: {
函數名 (state, 可選值) {
// 同步修改state值代碼
}
}
})
*/
具體代碼
const store = new Vuex.Store({
state: {
count: 100 // 庫存
},
mutations: {
addCount (state, value) { // 負責增加庫存的管家
state.count += value
},
subCount (state, value) { // 負責減少庫存的管家
state.count -= value
},
setCount (state, value) { // 負責直接修改庫存的管家
state.count = value;
}
}
})
註意
- mutations是唯一能修改state的地方, 確保調試工具可以追蹤變化
- mutations函數內, 只能寫同步代碼, 調試工具可追蹤變化過程
- 因為調試工具要立刻產生一次記錄, 所以必須是同步的
小結
-
mutations里函數作用?
- 負責修改state里的數據
-
mutations只能寫什麼樣的代碼?
- 同步流程的代碼
七、vuex-mutations使用
目標
- 使用mutations2種方式
- mutations註意事項
使用mutations的2種方式
-
方式1: 組件內 - 直接使用
語法:
this.$store.commit("mutations里的函數名", 具體值)
-
方式2: 組件內 - 映射使用
語法:
// 1. 拿到mapMutations輔助函數 import { mapMutations } from 'vuex' export default { methods: { // 2. 把mutations里方法映射到原地 ...mapMutations(['mutations里的函數名']) } }
AddItem直接用
- 點擊事件綁定
- 提交mutations傳入值
<button @click="addFn">庫存+1</button>
<script>
export default {
methods: {
addFn(){
this.$store.commit('addCount', 1)
}
}
}
</script>
App.vue直接用
- 觸發計算屬性的set方法
- 提交mutations傳入值
<span>庫存總數: </span>
<input type="text" v-model="count">
<script>
export default {
computed: {
count: {
set(val){
this.$store.commit('setCount', val) // 把表單值提交給store下的mutations
},
get(){
return this.$store.state.count
}
}
}
}
</script>
SubItem映射用
- 點擊事件
- 映射mutations的方法
- 調用mutations方法傳值
<button @click="subFn">庫存-1</button>
<script>
// 需求2: 映射mutations到方法里
// 1. 拿到輔助函數 mapMutations
// 2. 在methods內, ...mapMutations(['mutations函數名'])
// 3. 當普通方法使用
import { mapMutations } from 'vuex'
export default {
methods: {
...mapMutations(['subCount']),
subFn(){
this.subCount(1)
}
}
}
</script>
註意
mutations函數上, 只能接收一個參數值, 如果傳對個, 請傳一個對象
小結
-
mutations有哪2種使用方式?
直接使用 this.$store.commit()
映射使用 mapMutations把方法映射到組件內直接調用
-
state, mutations, 視圖組件, 3個關係是什麼?
八、vuex-actions定義-非同步修改
目標
- 定義actions
定義actions
在store/index.js定義actions
語法:
/*
const store = new Vuex.Store({
actions: {
函數名 (store, 可選值) {
// 非同步代碼, 把結果commit給mutations給state賦值
}
}
})
*/
具體代碼:
const store = new Vuex.Store({
// ...省略state和mutations此處
actions: {
asyncAddCount(store, num){
setTimeout(() => { // 1秒後, 非同步提交給add的mutations
store.commit('addCount', num)
}, 1000)
},
asyncSubCount(store, num) {
setTimeout(() => { // 1秒後, 非同步提交給sub的mutations
store.commit('subCount', num)
}, 1000)
}
}
})
小結
-
actions和mutations區別?
mutations里同步修改state
actions里放入非同步操作
-
actions是否能操作state?
不建議, 要commit給mutations(為調試工具可追蹤)
-
actions和mutations里函數, 第一個形參分別是什麼?
mutations的是state
actions的是store
九、vuex-actions使用
目標
- 使用actions
使用actions的2種方式
-
方式1: 組件內 - 直接使用
語法:
this.$store.dispatch('actions函數名', 具體值)
-
方式2: 組件內 - 映射使用
語法:
// 1. 拿到mapActions輔助函數 import { mapActions } from 'vuex' export default { methods: { // 2. 把actions里方法映射到原地 ...mapActions(['actions里的函數名']) } }
AddItem直接用
- 點擊事件
- dispatch觸發action
<button @click="asyncAddFn">延遲1秒, 庫存+5</button>
<script>
export default {
methods: {
asyncAddFn(){
this.$store.dispatch('asyncAddCount', 5)
}
}
}
</script>
SubItem映射用
- 點擊事件
- 映射actions的方法
- 調用actions的方法傳值
<button @click="asyncSubFn">延遲1秒, 庫存-5</button>
<script>
// 需求3: 映射actions到方法里
// 1. 拿到輔助函數 mapActions
// 2. 在methods內, ...mapActions(['actions函數名'])
// 3. 當普通方法使用
import { mapActions } from 'vuex'
export default {
methods: {
...mapActions(['asyncSubCount']),
asyncSubFn(){
this.asyncSubCount(5)
}
}
}
</script>
小結
-
actions使用方式?
方式1: this.$store.dispatch('actions方法名字', 值)
方式2: ...mapActions(['actions里的方法名']) 映射到原地使用
-
視圖組件, state, mutations, actions的關係是?
十、vuex-重構購物車-準備Store
目標
- 在現有項目如何集成vuex
store準備
- 複製預習資料<shopcar-模板>到自己今天文件夾下
- 下載vuex
- store/index.js創建導出store對象
- main.js把store引入, 然後註入到Vue實例
小結
-
現有項目如何集成vuex
下載vuex
創建store對象並註入到Vue實例中
十一、vuex-重構購物車-配置項(上午結束)
目標
- 準備state和mutations還有actions
配置項準備
- 定義state - 保存商品列表數組
state: {
goodsList: [] // 列表
}
- 定義mutations - 給state里變數賦值
mutations: {
setGoodsList(state, newList) {
state.goodsList = newList
}
}
- 定義actions - 非同步請求數據提交給mutations
actions: {
async asyncGetGoodsList(store) {
const url = `https://www.escook.cn/api/cart`
// 發送非同步請求
const res = await axios({ url: url });
store.commit('setGoodsList', res.data.list) // 提交mutation修改state中的數據
}
}
App.vue使用vuex
- 把vuex商品數組映射回來使用
- 網路請求調用actions方法
<script>
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState({list: 'goodsList'}) // 自定義原地屬性名list, 映射vuex里的goodsList變數值
},
created(){
this.asyncGetGoodsList()
},
methods: {
...mapActions(['asyncGetGoodsList']),
allFn(bool){
this.list.forEach(obj => obj.goods_state = bool)
}
}
}
</script>
小結
-
mapState可以改變映射到原地的計算屬性名嗎?
可以的, 格式...mapState({''計算屬性名', 'state里要映射的變數名'})
十二、vuex-getters定義-計算屬性
目標
- getters概念
- 定義getters
getters概念
vuex身上的全局狀態-計算屬性, 類似於computed
getters 依賴於 state中原始數據的變化,並返回計算後的新數據
定義getters
在store/index.js定義getters
語法:
/*
const store = new Vuex.Store({
getters: {
計算屬性名 (state) {
return 值給計算屬性
}
}
})
*/
具體代碼
const store = new Vuex.Store({
// ...省略其他
getters: {
allCount(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state === true) { // 選中商品才累加數量
sum += obj.goods_count;
}
return sum;
}, 0)
},
allPrice(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state) {
sum += obj.goods_count * obj.goods_price
}
return sum;
}, 0)
}
}
})
小結
-
getters有什麼用?
vuex里的計算屬性, 屬於全局計算屬性, 類似computed
十三、vuex-getters使用
目標
- 組件內使用getters
使用getters的2種方式
-
方式1: 組件內 - 直接使用
語法:
this.$store.getters.計算屬性名
-
方式2: 組件內 - 映射使用
語法:
// 1. 拿到mapGetters輔助函數 import { mapGetters } from 'vuex' export default { computed: { // 2. 把getters里屬性映射到原地 ...mapGetters(['getters里的計算屬性名']) } }
MyFooter.vue里使用
- 使用2種方式給計算屬性值
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
allCount(){
return this.$store.getters.allCount;
},
...mapGetters(['allPrice'])
}
}
</script>
小結
-
getters如何使用?
方式1: this.$store.getters.計算屬性名
方式2: ...mapGetters(['getters里計算屬性名'])
十四、vuex-modules定義-分模塊
目標
- 為何要分模塊
- modules定義
為何分模塊
代碼上的對比
創建modules模塊對象
- 新建store/modules/user.js
- 新建store/modules/cart.js
語法: 對象里包含5個核心概念, 只有state變成函數形式
user.js - 用戶模塊對象
// 用戶模塊對象
const userModule = {
state(){
return {
name: "",
age: 0,
sex: ''
}
},
mutations: {},
actions: {},
getters: {}
}
export default userModule
cart.js - 購物車模塊對象
// 購物車模塊對象
import axios from 'axios'
const cartModule = {
state() {
return {
goodsList: []
}
},
mutations: {
setGoodsList(state, newList) {
state.goodsList = newList
}
},
actions: {
async asyncGetGoodsList(store) {
const url = `https://www.escook.cn/api/cart`
// 發送非同步請求
const res = await axios({ url: url });
store.commit('setGoodsList', res.data.list) // 提交mutation修改state中的數據
}
},
getters: {
allCount(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state === true) { // 選中商品才累加數量
sum += obj.goods_count;
}
return sum;
}, 0)
},
allPrice(state) {
return state.goodsList.reduce((sum, obj) => {
if (obj.goods_state) {
sum += obj.goods_count * obj.goods_price
}
return sum;
}, 0)
}
}
}
export default cartModule
定義modules
語法:
modules: {
模塊名: 模塊對象
}
- 把2個模塊對象, 引回到store里註冊
import Vue from 'vue'
import Vuex from 'vuex'
import cartModule from './modules/cart'
import userModule from './modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user: userModule,
cart: cartModule
}
})
export default store
小結
-
為什麼分模塊?
集中式管理項目過大, 變數過多, 會導致state臃腫, 難以維護
-
如何分模塊?
定義模塊對象, state變成函數返回對象形式, 每個模塊都有state/mutations/actions/getters/modules
-
根store如何註冊?
modules里 { 模塊名: 模塊對象 }
十五、分模塊-影響state取值方式
目的
- 只要分模塊, state取值方式改變, 其他暫時不變
state使用方式修改
-
方式1: 組件內 - 直接使用
原語法:
this.$store.state.變數名
分模塊後語法:
this.$store.state.模塊名.變數名
-
方式2: 組件內 - 映射使用
原語法:
...mapState(['state里變數名']) ...mapState({'變數名': "state里變數名"}) // 給映射過來的state起別的名字
分模塊後語法:
...mapState({ '變數名': state => state.模塊名.變數名 })
App.vue-修改
computed: {
// ...mapState({list: 'goodsList'}) // 本地屬性名list, 映射vuex里的goodsList變數值
// 方式1: 直接用
// list(){ // 這個list就是組件內普通的計算屬性名
// return this.$store.state.cart.goodsList
// }.
// 方式2: 映射方式改變
...mapState({'list': state => state.cart.goodsList})
},
小結
-
分模塊對什麼有影響?
對state的取值方式有影響, 對其他暫無影響
-
state如何取值?
在組件使用的時候, 要state.模塊名.變數名
十六、分模塊-命名空間
目標
- 防止多個模塊之間, mutations/actions/getters的名字衝突
開啟命名空間
在模塊對象內設置namespaced: true
const moduleShopCar = {
namespaced: true,
state () {},
mutations: {},
actions: {},
getters: {},
modules: {}
}
state使用方式修改
-
直接使用無變化: this.$store.state.模塊名.變數名
-
輔助函數需要遵守格式
...mapState("模塊名", ['state變數名'])
mutations使用方式修改
-
方式1: 組件內 - 直接使用
-
原語法:
this.$store.commit("mutations里的函數名", 具體值)
-
開命名空間後語法:
this.$store.commit("模塊名/mutations里的函數名", 具體值)
-
-
方式2: 組件內 - 映射使用
-
原語法:
...mapMutations(['mutations里方法名'])
-
開命名空間後語法:
...mapMutations("模塊名", ['mutations里方法名'])
-
actions使用方式修改
-
方式1: 組件內 - 直接使用
-
原語法:
this.$store.dispatch("actions里的函數名", 具體值)
-
開命名空間後語法:
this.$store.dispatch("模塊名/actions里的函數名", 具體值)
-
-
方式2: 組件內 - 映射使用
-
原語法:
...mapActions(['actions里方法名'])
-
開命名空間後語法:
...mapActions("模塊名", ['actions里方法名'])
-
getters使用方式修改
-
方式1: 組件內 - 直接使用
-
原語法:
this.$store.getters.計算屬性名
-
開命名空間後語法:
this.$store.getters['模塊名/計算屬性名']
-
-
方式2: 組件內 - 映射使用
-
原語法:
...mapGetters(['getters里計算屬性名'])
-
開命名空間後語法:
...mapGetters("模塊名", ['getters里計算屬性名'])
-
小結
- state和mutations, 在根store和開啟命名空間里的區別?
-
整個vuex的體系是?
十七、Vuex的構造
1.actions
- 由子組件this.$store.dispatch('actions名',傳遞的數據)觸發
- 傳遞的數據只能是單個數據,多個數據用對象傳遞
- actions: { action名({commit},數據){...}}
- store中actions內,commit用於觸發mutations,actions只做業務邏輯,不修改state
2.mutations
- 由actions中的commit('mutations名',傳遞的數據)觸發
- mutations:{mutations名(state,數據){...}}
- store中的mutations內,mutations可以修改state中的數據
3.state
- 存儲數據:state:{userInfor:{}}
- 可以通過mutations存儲或者修改,也是getters裡面計算屬性的依據
4.getters
- 計算state中的數據:getters:{getters名(state){...}}
- state用於getters計算屬性的依據
十八、Vuex中的模塊(module)和命名空間(namespaced)
1.模塊(module)
- 由於使用單一狀態樹,應用的所有狀態會集中到一個比較大的對象。當應用變得非常複雜時,store 對象就有可能變得相當臃腫。
為瞭解決以上問題,Vuex 允許我們將 store 分割成模塊(module)。每個模塊擁有自己的state、mutations、actions、getters、甚至是嵌套子模塊。
2.命名空間(namespaced)
-
預設情況下,模塊內部的 actions、mutations 和 getters 是註冊在全局命名空間的——這樣使得多個模塊能夠對同一 mutations 或 actions 作出響應,如果希望你的模塊具有更高的封裝度和復用性,你可以通過添加 namespaced: true 的方式使其成為帶命名空間的模塊。當模塊被註冊後,它的所有 getters、actions 及 mutations 都會自動根據模塊註冊的路徑調整命名。
-
如果你想模塊之間相互獨立、互不影響。可以通過添加 namespaced: true 的方式使其成為帶命名空間的模塊,當模塊被註冊後,它的所有 getters、actions 和 mutations 都會自動根據模塊註冊的路徑調整命名。所以開啟命名空間的模塊中的getters、actions 和 mutations的使用方式都會改變;但是開啟命名空間和不開啟命名空間的模塊中的state的使用方式不會改變。格式依然是store.state.模塊名.狀態名。
// 開啟store子模塊的命名空間 const moduleName = { state: {}, getters: {}, mutations: {}, actions: {}, namespaced: true // 開啟命名空間 } export default moduleName
// 在組件中使用 import { mapState, mapGetters, mapActions } from 'vuex' export default { computed: { // 傳統方式:獲取store中的數據 proData () { return this.$store.state.productModule.proData }, themeData () { return this.$store.getters['themeModule/themeData'] }, proName () { return this.$store.getters['productModule/proName'] }, proDesc () { return this.$store.getters['productModule/proDesc'] }, indexData () { return this.$store.getters['productModule/indexData'] } // 輔助函數方式一:獲取store中的數據(代碼較簡潔) ...mapState({ proData: state => state.productModule.proData }) ...mapGetters(['themeModule/themeData']) ...mapGetters(['themeModule/proName', 'themeModule/proDesc', 'themeModule/indexData']) // 輔助函數方式二:獲取store中的數據(代碼最簡潔) ...mapState('productModule', { proData: state => state.proData }) ...mapGetters('themeModule', ['themeData']) ...mapGetters('productModule', ['proName', 'proDesc', 'indexData']) }, created () { // 傳統方式:獲取非同步數據 this.$store.dispath('themeModule/queryThemeAction') this.$store.dispath('productModule/queryProDataAction') this.$store.dispath('productModule/queryIndexDataAction') // 輔助函數方式:獲取非同步數據(需要在methods中使用mapActions定義方法) this.queryThemeAction() this.queryProDataAction() this.queryIndexDataAction() }, methods: { ...mapActions('themeModule', ['queryThemeAction']) ...mapActions('productModule', ['queryProDataAction', 'queryIndexDataAction']) } }
擴展: 使用Devtools調試vuex數據
優秀的調試工具可以使我們寫程式事半功倍,最後我們再學習一下如果使用dev-tools來調試vuex中的數據,這也是數據可預測特性里不可缺少的一環
目標
- 掌握dev-tools調試vuex
- 理解什麼是數據狀態是可追蹤的
如何進行調試
註意只有vue+vuex的項目才可以用