Search code examples
vue.jsvuejs2vuex

Vue DOM not reactive to computed property


I have a button that is set to be disabled if a computed property's valid property is false. If true, the button should be enabled and allow a user to move to the next step in the current flow.

My currentStep computed property is updating perfectly on changes to the current step's inputs, but the button :disabled="currentStep.valid" isn't recognizing the changes that ARE HAPPENING to currentStep.valid.

If I click on the current component (addnewprogram) in vue-devtools to see it's data, the button displays correctly!

Seen here: http://recordit.co/XH6HX7JLhV

However, without clicking on addnewprogram in the devtools, it doesn't function correctly.

Is there an obvservation caveat I'm missing?

The code for this functionality can be found here:

<template>
  <section class="newprogram">

      <div class="newprogram--content">

        <div class="newprogram--stepone" v-if="progression.current === 1">
          <div class="content--left">
            <a class="link uppercase">use existing program information<i class="fa fa-picture-o"></i></a>
            <base-input v-for="input in currentStep.inputs"
                        :key="input.id"
                        :data="input"
                        v-model="input.value"></base-input>
          </div>
          <div class="content--right">
            <!-- images -->
          </div>
        </div>

        <div class="newprogram--steptwo" v-if="progression.current === 2">
          <choice-progression :step="1"></choice-progression>
        </div>

      </div>
    </div>

    <!-- Consistent among all steps -->
    <div class="container--bottomnav">
      <div class="bottomnav--left">
        <base-btn class="button-fluid"
                  :data="currentStep.btns[0]"></base-btn>
      </div>
      <div class="bottomnav--right">
        <base-btn :data="currentStep.btns[1]"
                  :disabled="currentStepValid"></base-btn>
      </div>
    </div>
    <!-- -->

  </section>
</template>

<script>
import bottomNav from '../main/bottom-nav.vue';
import baseProgressionBarbell from '../base/base-progression-barbell.vue';
import baseInstruction from '../base/base-instruction.vue';
import baseInput from '../base/base-input.vue';
import baseBtn from '../base/base-btn.vue';
import choiceProgression from '../secondary-flows/choice-progression.vue';

export default {
  name: 'addNewProgram',
  components: {
    bottomNav,
    baseProgressionBarbell,
    baseInstruction,
    baseInput,
    baseBtn,
    choiceProgression
  },
  computed: {
    progression () {
      return this.$store.getters.getProgression('addnewprogram');
    },
    steps () {
      return this.$store.getters.getSteps('addnewprogram');
    },
    currentStep () {
      return this.steps[this.progression.current - 1];
    },
    currentStepValid () {
      return this.currentStep.valid == false ? true : false;
    },
    stepOneValidation () {
      this.steps[0].inputs.forEach(input => {
        if (!input.value) {
          return this.$set(this.steps[0], 'valid', false);
        }
        this.$set(this.steps[0], 'valid', true);
      });
    },
    stepTwoChoices() {
      return this.$store.getters.getChoices('addnewprogram', 1);
    }
  }
}
</script>

<style lang="sass" scoped>
@import '../../sass/_variables.sass'

.newprogram
  display: flex
  flex-direction: column

.container--newprogram
  display: flex
  flex-direction: column
  height: 100%
  padding: $s1

.newprogram--header
  display: flex
  justify-content: space-between
  align-items: center

  h1
    padding: 0

.newprogram--content
  display: flex
  // justify-content: center
  // align-items: center
  height: 100%
  padding-top: $s2
</style>

Solution

  • You are updating members of a computed item. Computed items aren't editable. You need a data item, or you need to write your changes to the $store and have them refresh from there.