Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

v-model for child component and v-model inside child component Vue

Is there a way to simplify this code?

The button should also change the localValue of the child.

Vue.component('my-input', {
  template: `
    <div>
      <b>My Input:</b> <br>
      localValue: {{ localValue }} <br>
      <input v-model="localValue">
    </div>
  `,
  props: ['value'],
  data() {
    return { localValue: this.value }
  },
  watch: {
    value () {
      this.localValue = this.value
    },
    localValue () {
      this.$emit('input', this.localValue)
    }
  }
})

new Vue({
  el: '#app',
  data: () => ({
    parentValue: 'Inital value'
  }),
  methods: {
    change () {
      this.parentValue = 'Changed value'
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <my-input v-model="parentValue"></my-input>

  <button @click="change">Change</button><br>

  parentValue: {{ parentValue }}
</div>

I have always faced difficulties when I need to do so.

I will be very grateful for the help!

like image 236
Илья Зеленько Avatar asked Sep 09 '18 23:09

Илья Зеленько


People also ask

Can you have multiple V models?

Using v-model multiple times for one component Since we can name our v-model , we can use multiple of them on a single component. We have to be sure to name each one uniquely so the props/events are unique! Let's add a second v-model to our input called lastName .

What is the difference between v-model and V-bind?

v-model is for two way bindings means: if you change input value, the bound data will be changed and vice versa. But v-bind:value is called one way binding that means: you can change input value by changing bound data but you can't change bound data by changing input value through the element.

How do you call a method in child component Vue?

To call a method in a child component with Vue. js, we can pass in a prop from the parent component to its child. Then in the child component, we watch the prop's value and run the method we want. in the child component to register the testProp prop and add the sayHello method.


1 Answers

If you avoid using v-model inside your custom form component, you really only need

<b>My Input:</b> <br>
localValue: {{ value }} <br>
<input :value="value" @input="$emit('input', $event.target.value)">

No data, no watch, that's it.

See https://vuejs.org/v2/guide/components.html#Using-v-model-on-Components


If you really want something representing a value local to your component, the Vue docs favour using computed values over watchers (ref: https://vuejs.org/v2/guide/computed.html#Watchers).

The idea here is to create a computed value with getter and setter to facilitate a simplified one-way data flow.

Vue.component('my-input', {
  template: `<div><b>My Input:</b> <br>localValue: {{ localValue }} <br><input v-model="localValue"></div>`,
  props: ['value'],
  computed: {
    localValue: {
      get () {
        return this.value
      },
      set (value) {
        this.$emit('input', value)
      }
    }
  }
})

new Vue({
  el: '#app',
  data: () => ({
    parentValue: 'Inital value'
  }),
  methods: {
    change () {
      this.parentValue = 'Changed value'
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <my-input v-model="parentValue"></my-input>

  <button @click="change">Change</button><br>

  parentValue: {{ parentValue }}
</div>
like image 101
Phil Avatar answered Sep 28 '22 20:09

Phil