// 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
// 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
<!-- User.vue -->
<template>
<div class="details">
<div class="username">User: {{ nameUpperCase }}</div>
<input :value="name" @keyup="updateName($event.target.value)" />
</div>
</template>
<script lang="ts">
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
}
</script>
And a variant of the similar @MutateAction:
// 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 -
*
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:
And a variant of the similar
@MutateAction
: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 MutationActionParamsWell, it works. But it's too much code duplication and dumb.