Cananau Cristian
Cananau Cristian

Reputation: 456

vue js sync modifier doesn't update the input value

I have a beginner question about sync modifier in vuejs. In my example, i want to change the value of inputs depending on focus event. The value is an Object inputsData and i'm getting it from the app. In parent i'm passing it to the child where it is rendering. I set an timer because i want to emit an server request. As you can see in the handleFocusFromChild Methode it change me the dataToBeChanged with newData (se also log after 4 seconds). As i understood from vue guid it should to update also the input value but it doens't, and i don't understand why, because dataToBeChanged have now the new values from newData. Can someone explain me why and how should i do to make it work?

Here i'm using the the Parent:

import Parent from "./parent.js";

Vue.component("app", {
  components: {
    Parent
  },
  template: `
           <div>
             <parent :inputsData="{
                                   'firstElement':{'firstInputValue':'Hi there'},
                                   'secondElement':{'secondInputValue':'Bye there'}
                                    }"></parent>
           </div>
            `
});


Here is the Parent:

import Child from "./child.js";
export default {
  name: "parent",
  components: {
    Child
  },
  props: {
    inputsData: Object
  },
  template: ` 
         <div>
           <child @focusEvent="handleFocusFromChild"
                  :value.sync="inputsData.firstElement.firstInputValue"></child>
           <child @focusEvent="handleFocusFromChild"  
                  :value.sync="inputsData.secondElement.secondInputValue"></child>
           </div>
            `,
  computed: {
    dataToBeChanged: {
      get: function() {
        return this.inputsData;
      },
      set: function(newValue) {
        this.$emit("update:inputsData", newValue);
      }
    }
  },
  methods: {
    handleFocusFromChild: function() {
      var newData = {
        firstElement: { firstInputValue: "Hi there is changed" },
        secondElement: { secondInputValue: "Bye there is changed" }
      };
      setTimeout(function() {
        this.dataToBeChanged = newData;
      }, 3000);

      setTimeout(function() {
        console.log(this.dataToBeChanged);
      }, 4000);
    }
  }
};

Here is the child:

export default {
  template: `
              <div class="form-group">
                <div class="input-group">
                  <input @focus="$emit('focusEvent', $event)"
                         v-model="value">
                </div>
              </div>
            `,
  props: {
    value: String
  }
};

Upvotes: 0

Views: 2745

Answers (1)

Jo&#227;o Victor
Jo&#227;o Victor

Reputation: 639

you child component should emit "this.$emit('update:value', newValue)" as event take a look over the docs: https://br.vuejs.org/v2/guide/components-custom-events.html

Also a way to do it is like this:

export default {
  template: `
              <div class="form-group">
                <div class="input-group">
                  <input @focus="$emit('focusEvent', $event)"
                         v-model="valueProp">
                </div>
              </div>
            `,
  props: {
    value: String
  },
  computed: {
    valueProp:{
            get(){
                return this.value
            },

            set(val){
                return this.$emit("update:value", val);
            }
        },
  }
  methods: {
    handleFocus() {
      this.$emit("focusEvent");
    }
  }
};

Upvotes: 1

Related Questions