英文使用说明地址https://championswimmer.in/vuex-module-decorators/
1、安装
2、概述
2.1 功能
这个库可以使用下面方式编写 vuex
模块
对应输出结果为
2.2 类型安全的好处
而不是使用通常的方式来dispatch
和commit
它没有为有效负载提供类型安全,也没有在 IDE 中提供自动完成帮助, 您现在可以使用 getModule
访问器使用更多类型安全机制
3、开始
3.1 定义module
To define a module, create a class that extends from VuexModule
and must be decorated with Module
decorator
CAREFUL
There is a Module
class in the vuex
package too, which is not a
decorator. Make sure you import correct Module decorator from from
vuex-module-decorators
❌ import {Module} from 'vuex'
✔️ import {Module} from 'vuex-module-decorators'
3.2 store内使用
In your store, you use the MyModule
class itself as a module.
NOTE
The way we use the MyModule class is different from classical object-oriented programming
and similar to how vue-class-component works.
We use the class itself as module, not an object constructed by the class
new MyModule()
❌
3.3 访问状态
All the usual ways of accessing the module works -
- Import The store
- Use
this.$store
if in component
In addition to that, for a much more typesafe access, we can use getModule()
- Use
getModule()
to create type-safe accessor
4、核心内容
4.1 State
All properties of the class are converted into state props.
For example, the following code
is equivalent of this -
🚨 WARNING
If state value cannot be determined, it MUST be initialized with null
. Just like wheels: number | null = null
.
4.2 Getters
All ES6 getter functions of the class are converted into vuex getters
For example, the following code -
is equivalent of this -
For Method-Style Access use vanilla vuex and return a function:
4.3 Mutations
All functions decorated with @Mutation
are converted into Vuex mutations
For example, the following code -
is equivalent of this -
NOTE
Once decorated with the @Mutation
decorator Mutations are run with this (context) set to the state
So when you want to change things in the state,
state.item++
is simply this.item++
🚨 WARNING
Mutation functions MUST NOT be async functions.
Also do not define them as arrow ➡️ functions, since we need to rebind them at runtime.
4.4 Actions
All functions that are decorated with @Action
are converted into
vuex actions.
For example this code -
is equivalent of this -
NOTE
Once decorated with @Action
the function will be called with this
having the following shape - {...[all fields of state], context}
The action payload comes as an argument.
So to commit a mutation manually from within action’s body
simply call this.context.commit('mutationName', mutPayload)
🚨️️ WARNING
If you are doing a long running task inside your action, it is recommended
to define it as an async function. But even if you do not, this library
will wrap your function into a Promise and await it.
If you want something to actually happen synchronously, make it a Mutation
instead
Also do not define them as arrow ➡️ functions, since we need to rebind them at runtime.
4.5 MutationActions
If you have understood how Actions and Mutations work
you might have requirements for some functions that -
- first do an asynchronous action
- and then commit the resultant value to the store via a mutation
This is where a @MutationAction
comes to picture.
Here is a basic example
That gets converted to something like this
NOTE
Note that if S denotes the type of state, then the object returned from a
MutationAction
function must of type Partial<S>
The keys present inside the return value (for eg, here posts
) are replaced into
the store.NOTE
When a MutationAction
function returns undefined
, the mutation part of the
MutationAction
will not be called, and the state will remain the same.
5、进阶教程
5.1 Namespaced Modules
TIP
Before reading this, it is imperative you understand what are
namespaced modules
If you intend to use your module in a namespaced way, then
you need to specify so in the @Module
decorator.
NOTE
The name
field in the decorator should match the actual name
that you will assign the module to, when you create the store.
It isn’t exactly elegant to manually keep these two same, but it
is important. We have to convert this.store.dispatch('action')
calls into this.store.dispatch('name/action')
, and we need the
name
to be correct in the decorator to make it work
5.1.1 Registering global actions inside namespaced modules
In order to register actions of namespaced modules globally you can add a parameter root: true
to @Action
and @MutationAction
decorated methods.
This way the @Action
clear of MyModule
will be called by dispatching clear
although being in the namespaced module mm
.
The same thing works for @MutationAction
by just passing { root: true }
to the decorator-options.
NOTE
When registering an action globally it can not be called by the namespace’s name.
For the example that means, that the action can not be called by dispatching mm/clear
!
5.2 Dynamic Modules
tip
Before you read this secion, it is advised that you understand how
dynamic module registration works
Modules can be registered dynamically simply by passing a few properties into
the @Module
decorator, but an important part of the process is, we first
create the store, and then pass the store to the module.
Step 1: Create the Store
Step 2: Create the Dynamic Module
NOTE
As of now, we do not support dynamic + nested modules.IMPORTANT ⛔️
Make sure your imports/requires are ordered in such a way that
the store definition is executed before the module class is created.
It is important for the store to exist, and be passed into the
@Module
decorator for the module to get registered dynamically