Search code examples
javascriptvue.jsvuejs2vue-componentvuex

v-if not working without v-else using computed property that returns Vuex state


I am not sure where the problem is, however, basic v-if is just not working properly.

<template>
   <div>
       <select v-model="col.code">
            <option v-for="i in foo" :value="i.code">{{ i.code }}</option>
       </select>

       {{ col }}
       // { "code": "B" }

       <div v-if="col.code"> // not working
            {{ col.code }}
       </div>
   </div>
</template>


<script>
export default {
    data() {
       return {
           foo: [
            {code: 'A'},
            {code: 'B'},
            {code: 'C'}
           ]
       } 
    },
    created() {
        this.view();
    },
    watch: {
        '$route': 'view',
    },
    computed: {
        col() {
            return this.$store.state.col;
        }
    }
}
</script>

However, if i add v-else, result will be rendered.

I also found out, that if i am doing same thing, without computed property, but with data property directly, it is not working either. What makes it to work is to add around v-if statements.

<div>

    <select v-model="col.code">
        <option v-for="i in [1,2,3,4,5]" :value="i">{{ i }}</option>
    </select>

    <div v-if="col.code">
        {{ col }}
    </div>

</div>

Strange.


Solution

  • It looks that's no problem with <div v-if="col.code"> but binding the select to a computed property is wrong, so you should use a computed setter :

      computed: {
            col: {
                get(){
                  return this.$store.state.col;
                 
                  },
                set(newVal){
                  this.$store.commit('UPDATE_COL',newVal); 
                }  
            }
        }
    

    Vue.use(Vuex)
    //store instance
    const store = new Vuex.Store({
      state: {
        col: {
          code: 'A'
        }
      },
      mutations: {
        UPDATE_COL(state, payload) {
          state.col = payload
        }
      }
    })
    
    //vue instance
    let app = new Vue({
      el: '#app',
      store,
      data() {
        return {
          foo: [{
              code: 'A'
            },
            {
              code: 'B'
            },
            {
              code: 'C'
            }
          ]
        }
      },
      created() {
    
      },
    
      computed: {
        col: {
          get() {
            return this.$store.state.col;
    
          },
          set(newVal) {
            this.$store.commit('UPDATE_COL', newVal);
          }
        }
      }
    
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <script src="https://unpkg.com/vuex"></script>
    
    <div id="app">
      <select v-model="col.code">
        <option v-for="i in foo" :value="i.code">{{ i.code }}</option>
      </select>
    
    
      <div v-if="col.code">
       My code : {{ col.code }}
      </div>
    
    </div>