3
votes

I have the data from MySQL database in the form of "1" and "0" representing the boolean true and false.These values are set in the vue component in the following manner :

    data(){
    return {
    form : {
         attribute_1 : "1", //attribute 1 is true
         attribute_2 : "0", //attribute 2 is false
         attribute_3 : "1", //attribute 3 is true
          }
        }
       }

To maintain the two-way binding I am currently using the computed properties as follows :

 attribute1: {
            get(){
                return this.form.attribute_1 == "1" ? true : false ;
            },
            set(newValue){
                this.form.attribute_1 = newValue ? "1" : "0";
            }
        },
 attribute2: {
            get(){
                return this.form.attribute_2 == "1" ? true : false ;
            },
            set(newValue){
                this.form.attribute_2 = newValue ? "1" : "0";
            }
        }, ...

These computed properties are wired on HTML code in following manner.

<input type="checkbox"  checked v-model="attribute1">
<input type="checkbox"  checked v-model="attribute2">

This works quite good for the two way binding in VUE. But there is a severe repetition in the code.

There is another way I have in mind using the @change event to track the changes in the checkbox :checked property and change the data attributes according but It seems to be one way binding and in the Vue console values are only updated when the I refresh the VUE panel.

Is there is a better way to achieve two way binding in this particular scenario?

2

2 Answers

4
votes

My favorite solution is to create component to achieve that:
My Checkbox.vue component:

<template>
    <input type="checkbox" :checked="isChecked" @change="change" />
</template>

<script>
export default {
    props: {
        value: {}
    },
    computed: {
        isChecked() {
            return this.value === "1" || this.value === true;
        }
    },
    methods: {
        change(e) {
            this.$emit("input", e.target.checked ? "1" : "0");
        }
    }
};
</script>

and use it in other components:

<template>
    <div>
        <Checkbox v-model="isChecked" />
    </div>
</template>

<script>
import Checkbox from "./Checkbox";
export default {
    components: {
        Checkbox
    },
    data: () => ({
        isChecked: "1"
    })
};
</script>
3
votes

You can achieve this by simply updating your template like:

<input type="checkbox" v-model="form.attribute1" :true-value="1" :false-value="0">
<input type="checkbox" v-model="form.attribute2" :true-value="1" :false-value="0">

and that's it. You will not need any computed properties anymore. You will get this.form.attribute1 value as "1" when checkbox will be checked or "0" when unchecked. Also, if you set form.attribute1 value as "1" then the checkbox will be checked by default as shown in the demo below.

DEMO:

new Vue({
  el: '#app',
  data(){
    return {
      form: {
        attribute1: "1", //attribute 1 is true
        attribute2: "0"  //attribute 2 is false
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>
<div id="app">
  <input type="checkbox" v-model="form.attribute1" :true-value="1" :false-value="0">
  <label for="checkbox">{{ form.attribute1 }}</label><br/><br/>
  <input type="checkbox" v-model="form.attribute2" :true-value="1" :false-value="0">
  <label for="checkbox">{{ form.attribute2 }}</label><br/><br/>
</div>