Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use v-model with nested properties in Vue.js

I have created a form and I'm trying to understand how to use v-model with nested properties in Vue.js

This is the code for my template, as you can see I'm trying to reference the nested properties like so: form.dobDate, but how do I reference the properties (dobDate, dobMonth and dobYear) in mounted and watch? So that whatever I type remains there on page refresh?

<template>
  <div>
    <b-form novalidate>
      <b-form-select name="dobDate" id="dobDate" v-model="form.dobDate" :options="optionsDays"></b-form-select>

      <b-form-select name="dobMonth" id="dobMonth" v-model="form.dobMonth" :options="optionsMonths"></b-form-select>

      <b-form-input
        placeholder="Year of Birth"
        required
        autofocus
        class="form-control"
        name="year"
        id="year"
        min="0"
        max="2003"
        type="number"
        v-model="form.dobYear"
      ></b-form-input>

      <input type="text" v-model="name" />

      <b-button type="submit" variant="primary">Submit</b-button>
    </b-form>
    <b-card class="mt-3" header="Form Data Result">
      <pre class="m-0">{{ form }}</pre>
    </b-card>
  </div>
</template>

Here is script code:

<script>
export default {
  data() {
    return {
      name: "",
      form: {
        dobDate: {
          selected: ""
        },
        dobMonth: {
          selected: ""
        },
        dobYear: "",
        name: ""
      },
      optionsMonths: [
        "January",
        "February",
        "March",
        "April",
        "May",
        "June",
        "July",
        "August",
        "September",
        "October",
        "November",
        "December"
      ],
      show: true
    };
  },

  mounted() {
    if (localStorage.name) {
      this.name = localStorage.name;
    }
  },
  watch: {
    name(newName) {
      localStorage.name = newName;
    },
    deep: true
  },

  computed: {
    optionsDays() {
      return Array.from(Array(31).keys());
    }
  },

  methods: {
    onSubmit(evt) {
      evt.preventDefault();
      alert(JSON.stringify(this.form));
    },
    getDates() {
      return Array.from(Array(31).keys());
    }
  }
};
</script>

As you can see I have a form object, with nested properties inside it which I want to bind to, and I'm also using mounted() and watch to store the data in local storage for when the page refreshes or when submitting the form (no validation at the moment).

like image 308
ImranR Avatar asked Nov 06 '22 14:11

ImranR


1 Answers

You could watch the form deeply (accessing its nested field ) and loop through it values using :

  Object.keys(after).forEach(key=>{
          localStorage[key]=after[key]
       })
 watch: {
    form: {
      handler: function(after, before) {
        Object.keys(after).forEach(key=>{
          localStorage[key]=after[key]
       })
      },
      deep: true
    }
   }
like image 151
Boussadjra Brahim Avatar answered Nov 12 '22 16:11

Boussadjra Brahim