How can i use mapActions, or mapGetters with using classes?
in vuex they use:
computed: {
...mapState('foo', {
// state is the state of the foo/ module instead of root
bar: state => state.bar
}
},
methods: {
...mapActions('foo', [
// map this.doSomething() to this.$store.dispatch('foo/doSomething')
'doSomething'
])
}
We can specify component options object to @Component decorator, so you can just use these helpers.
@Component({
computed: {
...mapState('foo', {
bar: state => state.bar
}
},
methods: {
...mapActions('foo', [
'doSomething'
])
}
})
If you would like to write as more class-like style, I encourage you to write some custom decorators.
function Getter (getterType) {
return createDecorator((options, key) => {
if (!options.computed) options.computed = {}
options.computed[key] = function () {
return this.$store.getters[getterType]
}
})
}
@Component
class MyComp extends Vue {
@Getter('foo') bar
created () {
console.log(this.bar)
}
}
function MapGetters (namespace, states) {
return createDecorator(options => {
if (!options.computed) {
options.computed = {}
}
Object.assign(options.computed, mapGetters(namespace, states))
})
}
@Component
class MyComp extends Vue {
@MapGetters('some/namespace', ['getter1', 'getter2'])
created () {
console.log(this.getter1, this.getter2)
}
}
I found this way more functional and common with vue style
If you are using Typescript I would recommend @ktsn solution
function Getter (getterType) { return createDecorator((options, key) => { if (!options.computed) options.computed = {} options.computed[key] = function () { return this.$store.getters[getterType] } }) } @Component class MyComp extends Vue { @Getter('foo') bar created () { console.log(this.bar) } }
I couldn't get @ktsn's code to work. As far as I can tell these are the types:
import { createDecorator, VueDecorator } from 'vue-class-component';
import { ComponentOptions } from 'vue';
function Getter(getterName: string): VueDecorator {
return createDecorator((options: ComponentOptions<Vue>, key: string, index: number): void => {
if (options.computed === undefined) {
options.computed = {};
}
options.computed[key] = function(this: Vue) {
return this.$store.getters[getterName];
};
});
}
@Component
class MyComp extends Vue {
@Getter('info')
public info?: Info;
}
This compiles but MyComp::info doesn't get updated reactively from the store (it is always undefined). If I change it to be public info: Info | null = null then I get errors that info already exists in the data type, when it tries to set options.computer['info']. That makes sense to me. Declaring the field in the class adds it to data and the decorator adds it to computed and it can't be the same name in both, so how on earth is this supposed to work?
Just use https://github.com/ktsn/vuex-class
Most helpful comment
We can specify component options object to
@Componentdecorator, so you can just use these helpers.If you would like to write as more class-like style, I encourage you to write some custom decorators.