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);
}
}
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.
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.
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.
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.
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
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.
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);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With