Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use mapActions with vue + Typescript class component?

I would like to know whats the correct way of using ...mapActions([]) within a Typescript vue class component.

this is how I do it:

<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import { mapActions } from "vuex";

@Component
export default class UsersAdd extends Vue {
  userName: string = "";

    ...mapActions(["newUser"]) /*mapAction from vuex */
  addUser() {
    console.log("...adding new user");
    this.newUser(this.userName);
  }
}
</script>

and as you can tell it's not working...

with Javascript I do it this way.

methods:{
  ...mapActions(["newUser"])
}

How can I do it with Typescript class component?

Edit: I have tried it this way, but it's still not working

@Component({
  methods: {
    ...mapActions(["newUser"]) /*mapAction from vuex */
  }
})
export default class UsersAdd extends Vue {
  userName: string = "";

  addUser() {
    console.log("...adding new user");
    this.newUser(this.userName);
  }
}
like image 835
Evan Avatar asked Feb 06 '20 16:02

Evan


People also ask

How to create a typescript component in Vue?

A class component is a TypeScript class that extends the Vue object. In single-file components, make sure you set the <script> language to ts and export the class as default. Open App.vue in your code editor and create this example single-file component with TypeScript: Notice that the data properties are defined directly on the class and methods.

What is the Vue-class-Component Library?

The vue-class-component library is only compatible with Vue.js 2. In this article, we’ll look at how to create Vue.js apps with class-based components. We can start using class-based components by creating a project with the Vue CLI.

Does JetBrains support TypeScript and Vue?

TypeScript Vue Plugin is also needed to get type support for *.vue imports in TS files. WebStorm also provides out-of-the-box support for both TypeScript and Vue. Other JetBrains IDEs support them too, either out of the box or via a free plugin. Projects scaffolded via create-vue include pre-configured tsconfig.json.

How do I map an action to a component in typescript?

We can map actions in the store to the component in Typescript as this: The key is adding this someLoadDataAction!: () => any for static type check for Typescript. As an example, we have the function type defined as () => any, but you can change it to the actual return type from the action in your vuex store.


Video Answer


3 Answers

One other way could be to use custom decorator, which would replace a method in your component with a method from the vuex store.

function VuexAction(moduleName: string): any {
  return createDecorator((options: any, key: string) => {
    if (!options.methods) options.methods = {};
    options.methods[key] = function wrapperMethod(...args: any[]) {
      return this.$store._actions[`${moduleName}/${key}`][0](...args);
    };
  });
}

The decorator can be used like this:

@Component
export default class SomeComponent extends Vue {
  @VuexAction("vuexModuleName") vuexModuleActionName!: () => void;

  async doStuff () {
    this.vuexModuleActionName();
  }
}

The idea is based on docs about custom decorators:

https://class-component.vuejs.org/guide/custom-decorators.html

And a custom vuex getter decorator:

https://github.com/vuejs/vue-class-component/issues/56#issuecomment-272604193

like image 65
Aivaras Čiurlionis Avatar answered Oct 22 '22 13:10

Aivaras Čiurlionis


If you don't want to bring in yet another dependency (i.e. vuex-class). We can map actions in the store to the component in Typescript as this:

@Component({
  computed: {
    ...mapActions({
      someLoadDataAction: "someLoadDataAction"
    })
  }
})
export default class HelloWorld extends Vue {
  someLoadDataAction!: () => any;

  mounted() {
    console.log(this.someLoadDataAction);
  }
}

The key is adding this someLoadDataAction!: () => any for static type check for Typescript. As an example, we have the function type defined as () => any, but you can change it to the actual return type from the action in your vuex store.

like image 28
Yuchen Avatar answered Oct 22 '22 14:10

Yuchen


With help of Action annotation you can do this in that way. Installation npm install --save vuex-class

import { Action } from 'vuex-class'

@Component()
export default class UsersAdd extends Vue {
  userName: string = "";

  @Action('newUser')
  newUser!: (newUser: string) => void
  addUser() {
    console.log("...adding new user");
    this.newUser(this.userName);
  }
}
like image 6
mflorczak Avatar answered Oct 22 '22 13:10

mflorczak