f / f/vue-wait
vuex-module-decorators Integration
- Dominant language
- JavaScript
- Stars
- 2k
- Forks
- 98
- PR merge metrics
- No merged PRs in 30d
Description
Is there a way to integrate this with vuex-module-decorators? mapWaitingActions won't work here since the action ist mapped in by `@Action`.
Example taken from https://blog.logrocket.com/how-to-write-a-vue-js-app-completely-in-typescript/ but with modifications to make it work:
```
npm install vuex-module-decorators -D
npm install vuex-class -D
```
```ts
// store/modules/user.ts
import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'
import store from "@/store";
interface IUserState {
name: string
}
@Module({ store: store, namespaced: true })
export default class User extends VuexModule implements IUserState {
public name: string = ''
@Mutation
public setName(newName: string): void {
this.name = newName
}
get nameUpperCase() {
return this.name.toUpperCase();
}
@Action
public updateName(newName: string): void {
this.context.commit('setName', newName)
}
}
export default User
```
```ts
// store.ts
import Vue from 'vue'
import Vuex from 'vuex'
import User from '@/store/modules/user'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
user: User
}
})
export default store
```
```vue
import { Component, Vue } from 'vue-property-decorator'
import { namespace } from 'vuex-class'
const user = namespace('user')
@Component
export default class User extends Vue {
@user.State
public name!: string
@user.Getter
public nameUpperCase!: string
@user.Action
public updateName!: (newName: string) => void
}
```
And a variant of the similar `@MutateAction`:
```ts
// store/modules/user.ts
import {
Module, Mutation, MutationAction,
VuexModule, Action,
} from 'vuex-module-decorators';
import { Veterinarian, VeterinarianControllerApi, VeterinarianSpecialisationEnum } from '@/services';
import { Getter } from 'vuex-class';
import store from '@/store';
interface IUserState {
name: string
}
@Module({ store, namespaced: true })
export default class User extends VuexModule implements IUserState {
public name: string = 'defaultValue'
get nameUpperCase() {
return this.name.toUpperCase();
}
@MutationAction({ mutate: ['name'] })
async updateName(newName: string) {
return { name: newName };
}
}
```
Wrapping the invocation of the Actions would be nice to trigger the wait start and end.
What I tried:
I created my own `WaitingMutationAction` decorator. I just took the original one and wrapped the action with start and end:
WaitingMutationAction
```diff
export interface MutationActionParams {
mutate?: (keyof Partial)[]
rawError?: boolean
root?: boolean
}
-function mutationActionDecoratorFactory(params: MutationActionParams) {
+function waitingMutationActionDecoratorFactory(params: MutationActionParams) {
return function(
target: T,
key: string | symbol,
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>>
) {
const module = target.constructor as Mod
const action: Act = async function(
context: ActionContext,
payload: Payload
) {
try {
+ this._vm.$wait.start("test");
const actionPayload = await mutactFunction.call(context, payload)
context.commit(key as string, actionPayload)
} catch (e) {
if (params.rawError) {
throw e
} else {
console.error('Could not perform action ' + key.toString())
console.error(e)
return Promise.reject(e)
}
+ } finally {
+ this._vm.$wait.end("test");
}
}
const mutation: Mut = function(
state: typeof target | Store,
payload: Payload & { [k in keyof T]: any }
}
module.actions![key as string] = params.root ? { root: true, handler: action } : action
module.mutations![key as string] = mutation
}
}
-export function MutationAction(
+export function WaitingMutationAction(
target: { [k in keyof T]: T[k] | null },
key: string | symbol,
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>
): void
-export function MutationAction(
+export function WaitingMutationAction(
params: MutationActionParams
): (
target: T,
key: string | symbol,
descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise>
) => void
*
* @param paramsOrTarget the params or the target class
* @param key the name of the function
* @param descriptor the function body
* @constructor
*/
-export function MutationAction(
+export function WaitingMutationAction(
paramsOrTarget: MutationActionParams | M,
key?: string | symbol,
descriptor?: TypedPropertyDescriptor<(...args: any[]) => Promise>>
):
| ((
target: T,
@MutationAction({mutate: ['incrCount']})
async getCountDelta() {
return {incrCount: 5}
}
*
*/
- return mutationActionDecoratorFactory(paramsOrTarget as MutationActionParams)
+ return waitingMutationActionDecoratorFactory(paramsOrTarget as MutationActionParams)
} else {
/*
* This is the case when `paramsOrTarget` is target.
* i.e. when used as -
*
@MutationAction
async getCountDelta() {
return {incrCount: 5}
}
*
*/
- mutationActionDecoratorFactory({} as MutationActionParams)(
+ waitingMutationActionDecoratorFactory({} as MutationActionParams)(
paramsOrTarget as K,
key!,
descriptor!
)
}
}
```
Well, it works. But it's too much code duplication and dumb.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.