[Vuejs]-Why is Vue not reactive in this scenario?

1👍

Perhaps you have overcomplicated things a bit. The computed properties are meant for things like that.

So rather than having to add those cells dynamically using Vue.set every time, you could build up these "items" (or list of cells) while taking advantage of the computed reactivity.

Have a look the following example. The other "magic" is the computed setter part, where it sets the currently active button text:

new Vue({
  el: '#app',

  data: () => ({
    cols: [
      { id: 'a' },
      { id: 'b' },
      { id: 'c' }
    ],
    numRows: 2,
    selectedCell: {
      text: ''
    }
  }),

  computed: {
    inputText: {
      get() {
        return this.selectedCell.text;
      },
      set(value) {
        this.selectedCell.text = value;
      }
    },

    items() {
      return Array
        .apply(null, { length: this.numRows })
        .map(() => {
          return this.cols.map(col => ({
            cellId: col.id,
            text: 'default text'
          }))
        });
    }
  },

  methods: {
    setActive(col) {
      this.selectedCell = col;
    }
  }
})
.input-container {
  text-align: center;
}

table {
  margin: 1rem auto;
}

button.active {
  background-color: lightgreen;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="input-container">
    <label>Click a Button, Then Type Some Text Here</label><br />
    <input v-model="inputText" ref="text" />
  </div>

  <table>
    <tbody>
      <tr v-for="(cols, index) of items" :key="index">
        <td v-for="col of cols" :key="col.cellId">
          <button @click="setActive(col)" :class="{ active: selectedCell === col }">{{col.text}}</button>
        </td>
      </tr>
    </tbody>
  </table>
</div>
👤Yom T.

Leave a comment