5
votes

I am trying to use multiple checkboxes in single file component. And I need to computed property, but I have boolean newVal instead of array in my setter. Here is my code:

var demo = new Vue({
    el: '#demo',
    data: {
        _checkedNames: [] 
    },
    computed: {
      checkedNames: {
        get: function () {
          return this._checkedNames;
        },
        set: function (newVal) {
          console.log(newVal); //with computed we have true/false value instead of array
          this._checkedNames = newVal;
        }
      }
    }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="demo">
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>

So, you will see boolean value in the console.

Update 1. Detail case explanation

I'm using legacy code of the model, which is being passed as a parameter to vue component. And I need to bind component markup to the model's property (_checkedNames in code above simulates this model property). This property declared via getter/setter (sometimes just getter). And I want to use such a property in v-model construction. This case doesn't work for me. I guess vuejs can't wrap it correctly. And I'm loking for a solution (or a workaround) that will take in account mentioned restrictions.

Here is the same question in vue forum: https://forum.vuejs.org/t/v-model-multiple-checkbox-and-computed-property/6544

2
could you explain the problem here a little clearer? I didn't get it - Soorena
thank you for your response, I don't get the question since it lacks very basic implementation instructions given by vue js. for example, why all of these inputs have v-model="checkedNames"? how would you know which one is selected when all of them point to the same boolean value! what is the purpose of using _checkedNames? how it bounds to the template. I just don't get it. - Soorena
I suggest you to read a little more about Vue js itself on it's website. - Soorena
@Soorena thanks for your comment. This is multiple checkboxes implementation from vue docs. And _checkedNames need for computed property internal state. Could you check my repo please? - Dmitry Kurmanov
I cloned it, it was working perfectly fine with ES6 implentation that I replaced with the typescripts. I couldn't find the problem with ts. sorry - Soorena

2 Answers

6
votes

Properties that start with _ or $ will not be proxied on the Vue instance because they may conflict with Vue’s internal properties and API methods. You will have to access them as vm.$data._property.

From the official documentation.

6
votes

Here it is the working version:

var demo = new Vue({
  el: '#demo',
  data: {
    checkedNames: []
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="demo">
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>

if you want to use a computed property you can use it this way:

var demo = new Vue({
  el: '#demo',
  data: {
    checkedNames: []
  },
  computed : {
    checkedComputed () {
      return this.checkedNames
    }
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="demo">
  <input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
  <label for="jack">Jack</label>
  <input type="checkbox" id="john" value="John" v-model="checkedNames">
  <label for="john">John</label>
  <input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
  <label for="mike">Mike</label>
  <br>
  <span>Checked Names :</span>
  <span>{{ checkedComputed }}</span>
</div>