Ken Ramirez
Ken Ramirez

Reputation: 335

Custom input component ignores update from method

I did a custom input component, it works correctly but there is a problem: when i try to update its value from a method the model is updated but the input value still there.

This is my component: https://codepen.io/ken-ramirez/pen/JgyKad

const BasicInput = {
  template: '<input v-model="content" @input="handleInput" />',
  prop: ['value'],
  data () {
    return {
      content: this.value
    }
  },
  methods: {
    handleInput (e) {
      this.$emit('input', this.content)
    }
  }
}

new Vue({
  el: '#app',
  data: { name: '' },
  components: { BasicInput },
  methods: {
    restart() {
      this.name = ''
    }
  }
})

You can press on restart button to see what i mean.

Upvotes: 1

Views: 48

Answers (2)

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

Like @NikitaK mentioned in his answer you're making a typo , you should write props instead of prop, but i want to give a shorter solution without using watcher property only with this code @input="$emit('input',$event.target.value)"

Full example

const BasicInput = {
  template: `<input :value="value" @input="$emit('input',$event.target.value)" />`,
  props: ['value']

}

new Vue({
  el: '#app',
  data() {
  return{
     name: ''
  }},
  components: { BasicInput },
  methods: {
    restart() {
      this.name = ''
    }
  }
})
body {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>

<div id="app">
  <basic-input v-model="name"></basic-input>
  <p>
    <strong>Name:</strong> {{ name }}
  </p>
  <button @click="restart">restart</button>
</div>

Upvotes: 1

NikitaK
NikitaK

Reputation: 524

You have a mistake in your code: props, not prop.

But this is not enough, also you need to update your content manually, it's not reactive with value prop. Everything declared inside data is not reactive with its initial values.

const BasicInput = {
  template: '<input v-model="content" @input="handleInput" />',
  props: ['value'],
  data () {
    return {
      content: this.value
    }
  },
  methods: {
    handleInput (e) {
      this.$emit('input', this.content)
    }
  },
  watch: {
    value(val) {
      this.content = val;
    }
  }
}

Upvotes: 2

Related Questions