web-dev-qa-db-fra.com

v-model et composants enfants?

J'ai un formulaire et lie une entrée en utilisant v-model:

<input type="text" name="name" v-model="form.name">

Maintenant, je veux extraire l’entrée et en faire son propre composant, comment lier ensuite les valeurs du composant enfant à l’objet parents form.name?

31
panthro

comme indiqué dans la documentation ,

v-model N'est qu'un sucre syntaxique pour:

<input
  v-bind:value="something"
  v-on:input="something = $event.target.value">

Pour implémenter la directive v-model Pour un composant personnalisé:

  • spécifiez un prop value pour le composant
  • définissez une propriété de données sur la valeur de valueprop dans la méthode data (car vous ne devez pas modifier la valeur d'un prop à l'intérieur d'un composant).
  • émettre un événement input avec la valeur de la propriété data chaque fois qu'elle change

Voici un exemple simple:

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

new Vue({
  el: '#app',
  data() {
    return { foo: 'a', bar: 'b' }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="app">
  <!-- using v-model... -->
  <my-input v-model="foo"></my-input>
  
  <!-- is the same as this... -->  
  <my-input :value="bar" @input="bar = $event"></my-input>

  {{ foo }}<br>
  {{ bar }}
</div>
80
thanksd

utilisez sync dans votre instance principale et si vous utilisez vue> 2.2 votre besoin, utilisez emit dans le composant.

Vérifiez cette doc: - https://alligator.io/vuejs/upgrading-vue-2.3/#propsync

Un exemple simple (avec vue 2.5):

Vue.component('my-input', {
        template: '<input v-on:keyup="onChange($event)" :value="field"></div>',
        props: ["field"],
        methods: {
                onChange: function (event) {
                        this.$emit('update:field', event.target.value);
                }
        }
});

var vm = new Vue({
        el: '#app',
        data:{val: ''},
});
h1 span { color: red }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<div id='app'>
 <h1>
   value
   <span>{{ val }}</span>
 </h1>
        <my-input :field.sync="val">
   </my-input>
 </div>
15
fitorec

Vous pouvez également spécifier le :value et @input événements sur le composant enfant et tirer parti des événements au lieu de créer une surveillance.

MyInput.vue

<template>
  <input 
    :value="value" 
    @input="$emit('input', $event.target.value)" />
</template>

<script>
export default {
  props: ['value']
};
</script>

Screen.vue

<template>
  <my-input v-model="name" />
</template>

<script>
import MyInput from './MyInput.vue';

export default {
  components: { MyInput },
  data() {
    return {
      name: ''
    }
  }
};
</script>
4
Cameron Wilby