ktsn / vuex-class

Binding helpers for Vuex and vue-class-component

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

[Feature Request]: Combine @State and @Mutation into a @Computed annotation

JavascriptMick opened this issue · comments

I am trying to bind a checkbox to my Vuex Store. My understanding is that I need to use v-model:-

<b-form-checkbox id="onlyMineFilterCheckbox" v-model="onlyMineFilter">Show only Mine</b-form-checkbox>

To do the binding, I need to create a computed property on my component class. I can either do this...

export default class MyView extends Vue {
  @Mutation updateOnlyMineFilter;
  @State(state => state.onlyMineFilter) onlyMineFilterState: boolean;
  get onlyMineFilter() {
    return this.onlyMineFilterState;
  }
  set onlyMineFilter(value: boolean) {
    this.updateOnlyMineFilter(value);
  }

or, this ..

export default class MyView extends Vue {
  $store: any;
  get onlyMineFilter() {
    return this.$store.state.onlyMineFilter;
  }
  set onlyMineFilter(value: boolean) {
    this.$store.commit('updateOnlyMineFilter', value);
  }

The first option uses the vuex-class annotations which is consistent with the rest of my component, but it is verbose and the state/mutation members are only used once. The second option is less verbose but forces me to use $store directly, with the declaration of $store just to fool typescript which I don't like.

What would be best, I think would be if the state accessor and the mutation could be combined into a single annotation... something like this...

@Computed(state => state.onlyMineFilter, 'updateOnlyMineFilter') onlyMineFilter: boolean;

What do we think? I am happy to attempt the implementation if we think it is a good design.

Could we add a @Setter annotation here so we don't have to use the native get/set?

Could we add a @Setter annotation here so we don't have to use the native get/set?

what would that look like? not sure what you are proposing

oh, I just saw the mapGetters helper (https://vuex.vuejs.org/guide/getters.html#the-mapgetters-helper) maybe what I actually want is a mapSetters as well?

There is another library that allows for two-way-binding of simple form fields to store variables BUT it does not support typescript:

https://github.com/maoberlehner/vuex-map-fields

There is a real gap in the community for this feature.

Found an easy workaround for now using @change:

<template>
	<v-layout>
		<v-flex>
			<h3>{{ title }}</h3>
			<h4>
				Please enter your work email address and we’ll send you a passcode
			</h4>
			<p>Already registered? <a href="">Sign In</a></p>
			<v-text-field
				v-model="email"
				@change="updateEmail"
				placeholder="Work Email Address"
				outline
			></v-text-field>
			<p>
				To access Apple Employer Portal, enter your email address on file with
				your employer.
			</p>
			<v-btn @click="sendEmail()"></v-btn>
		</v-flex>
	</v-layout>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { State, Getter, Mutation, Action, namespace } from 'vuex-class'
import { oneTimePasscode } from '../store/oneTimePasscode'

@Component
export default class OneTimePasscode extends Vue {
	@Prop(String) title!: string
	@Action public sendEmail

	public email: string = ''
	@Mutation public updateEmail
	public created() {
		this.$store.registerModule('oneTimePasscode', oneTimePasscode)
	}
}
</script>

@jacklp @JavascriptMick If you're still interested, I just stumbled on the same issue for one of my project, and I just published a tiny library for 2 way binding : https://github.com/scleriot/vuex-class-state2way

sweet, will try and see if I can implement it

worked beautifully @scleriot

Is @scleriot 's state2way lib part of vuex-class now?

This should really be part of the library.

Still waiting for this new feature... what's happening to the project?