前两篇介绍完 Vuex 的核心概念,最後当中大型专案需要组织较为复杂的资料结构时,总不可能一个 index.js 就塞满所有资料量,这会造成取用和管理上的不便,因此势必得经过一番模组化,将过於庞大的资料分门别类,同时搭配使用 Map Helpers 来简化冗长程序码。
将 Store 分割成多组 module,每个 module 内部各自拥有其自己的 state、getter、mutation、action。
// member.js
export default ({
namespaced: true,
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
})
// store/index.js
import member from './member.js'
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
member,
...
}
})
在 module 内部设定 namespaced: true
,使其成为带有指定名称的 module,当 module 被注册之後,其内部拥有的所有注册路径也会跟着调整命名,取用时也能迅速得知模组来源。
store.state.member.name
store.getters["member/name"]
访问全域资料:
模组化的 getters 函式,可取用的参数依序为 state
、getters
、rootState
、rootGetters
。
store.state
和 store.getters
,差别在於 Vuex.Store 实例属性为唯读状态// root.js
state: {
number: 20
}
// member.js => module name: member
state: {
name: 'John'
}
getters: {
name: state => state.name,
}
// test.js => module name: test
getters: {
rootNumber: (state, getters, rootState) => rootState.number,
memberName: (state, getters, rootState, rootGetters) =>
rootGetters['member/name']
}
console.log(this.$store.getters["test/rootNumber"]) // 20
console.log(this.$store.getters["test/memberName"]) // John
dispatch
和 commit
的第三个可选参数(options?: Object
)若设定为 { root: true }
,则可跨域取用命名模组的 root actions 或 root mutations。
// member.js => module name: member
actions: {
getName: {...},
}
// test.js
actions: {
getAllData(context): {
context.dispatch("member/getName", null, { root: true });
},
}
注册为全域 action:在 action 内设定 { root: true }
,并将 action 函式定义为 handler
,便能在全域中使用 dispatch
呼叫该 action。
// member.js => module name: member
actions: {
getMemberName: {
root: true,
handler(context, payload) {...},
},
}
store.dispatch("member/getMemberName"); // 非全域 action
store.dispatch("getMemberName"); // 设定 root: true 注册为全域 action
初学时总会先使用最基本的语法来取用 Vuex 资料:
computed:{
name(){
return this.$store.getters["member/name"];
}
}
然而一旦取用的资料愈来愈多,并且资料皆来自不同的模组时,取用过程便会变成一长串重复又冗长的内容,因此 Map Helpers 正是解决困扰的重要帮手,四个核心概念各有所属的 Helper 物件——mapState
、mapGetters
、mapMutations
、mapActions
,透过物件展开运算符(Object Rest/Spread Properties for ECMAScript)简化程序码。
首先需将 Helper 引入:
import { mapGetters } from 'vuex'
mapGetters
阵列写法:应用於单层结构
computed: {
...mapGetters(['name','age','address','birth', ...])
}
物件写法:应用於模组化 Store
可以为 getter 重新命名:
computed: {
...mapGetters({
memberAge: 'member/age',
memberName: 'member/name',
})
}
// this.$store.getters["member/name"] 变成 this.memberName
相同模组的 getter 可以提取出模组名称:
computed: {
...mapGetters('member',{
memberAge: 'age',
memberName: 'name',
})
}
物件结合阵列写法:已提取模组名称,但无命名需求,则可结合阵列形式更为精简
computed: {
...mapGetters('member',['age','name'])
}
mapMutations
、mapActions
在 methods 中使用 mapMutations
及 mapActions
,两者也都可以带入 payload
参数。
import { mapMutations, mapActions } from 'vuex';
methods: {
...mapMutations({
books: 'bookList',
// this.$store.commit('bookList') 变成 this.books()
})
...mapActions(['fetchBookList', 'fetchBook']),
// this.$store.dispatch('fetchBookList') 变成 this.fetchBookList()
// this.$store.dispatch('fetchBook', ISBNId) 变成 this.fetchBook(ISBNId)
}
因为若一律透过 getter 取用 state,基本上就比较少有透过 mapState
取用 state 的机会,因此本篇就先略过介绍了,有兴趣的话也可以读 Vuex 文件「The mapState Helper」了解,用法上应该大同小异。
<<: 【DAY 22】Algorithm - Insertion sort 插入排序法
>>: Day 21:贪婪演算法(greedy algorithm)
前言 本日主要内容包含另一个网路撷取资料方式Convert HTML Tables To JSON、...
前一篇文章有提到该如何利用 SQLALchemy 建立一张资料表, 这篇文章主要是纪录该如何利用 S...
来找设计师一起 side project,前後端 / UIUX 皆可ㄛ。配对单连结: https:...
图片来源:https://www.lohaslife.cc/archives/18537 昨天最後...
前言: 最近公司专案上刚好碰到制作汇出报表模组开发,而过往我都是透过form submit方式直接将...