web-dev-qa-db-fra.com

Obtenir des données d'un seul composant Vue dans un autre composant?

J'utilise Vue.js 2.5.13 et avoir cette structure:

component-one.vue:

<template>
  <div>
    <input type="text" v-model="input_one">
    <component-two></component-two>
  </div>
</template>

<script>
  import ComponentTwo from 'component-two.vue'

  export default {
    name: "component-one",
    components: {
      ComponentTwo
    },
    data() {
      return {
        input_one: 'Hello from ComponentOne',
        input_two: ... // <-- I want to get value from ComponentTwo input_two (v-model) here
      }
    }
  }
</script>

component-two.vue:

<template>
  <div>
    <input type="text" v-model="input_two">
  </div>
</template>

<script>
  export default {
    name: "component-two",
    data() {
      return {
        input_one: 'Hello from ComponentTwo'
      }
    }
  }
</script>

Comment obtenir des données de ComponentTwo dans le composant ComponentOne? C'est important pour moi, car j'ai de nombreux composants similaires avec des champs (énorme formulaire de site d'inscription) et je n'ai aucune idée d'appeler des données entre les composants Vue ..

7
Vic Shóstak

Vous pouvez facilement y parvenir en utilisant un bus d'événements global.

https://alligator.io/vuejs/global-event-bus/

Pour les applications plus grandes et plus complexes, je recommanderais d'utiliser un outil de gestion d'état tel que vuex.

https://vuex.vuejs.org/en/

9
user320487

Vuejs utilise "props" pour la communication parents/enfants et les événements "emit" pour la communication enfants/parents

enter image description here

Vous devez vous rappeler que pour chaque accessoire que vous passez au composant enfant, vous devez avoir cet accessoire dans le tableau d'accessoires. La même chose s'applique aux événements, tous les événements que vous émettez doivent être capturés dans le composant parent, donc:

component-one.vue:

<template>
  <div>
    <input type="text" v-model="input_one">
    <component-two
        @CustomEventInputChanged="doSomenthing">
    </component-two>
  </div>
</template>

<script>
  import ComponentTwo from 'component-two.vue'

  export default {
    name: "component-one",
    components: {
      ComponentTwo
    },
    data() {
      return {
        input_one: 'Hello from ComponentOne',
        input_two: ''
      }
    },
    methods: {
        doSomenthing ( data ) {
            this.input_two = data;
        }
    }
  }
</script>

component-two.vue:

<template>
  <div>
    <input type="text" v-model="input_two" @change="emitEventChanged>
  </div>
</template>

<script>
  export default {
    name: "component-two",
    data() {
      return {
        input_one: 'Hello from ComponentTwo'
      }
    },
    methods: {
        emitEventChanged () {
            $emit('CustomEventInputChanged', this.input_two);
        }
    }

  }
</script>

Cela devrait fonctionner

3
Luca Giardina

Vous devez implémenter un système qui renvoie le v-modèle au parent.

Cela peut être fait en utilisant une propriété calculée à l'intérieur de component-two qui émet le changement dans sa méthode set.

Exemple:

Vue.component('component-two', {
  name: 'component-two',
  template: '#component-two-template',
  props: {
    value: {
      required: true,
      type: String,
    },
  },
  computed: {
    message: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit('input', val);
      },
    },
  },
});

var app = new Vue({
  el: '#app',
  data: {
    message1: 'm1',
    message2: 'm2',
  },
});
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<script type="text/x-template" id="component-two-template">
  <input type="text" v-model="message"/>
</script>
<div id="app">
  <input type="text" v-model="message1"/>
  <component-two v-model="message2"></component-two>
  <p>Output</p>
  <pre>{{message1}}</pre>
  <pre>{{message2}}</pre>
</div>
2
Ferrybig

Vous pouvez utiliser . Modificateur de synchronisation

<template>
  <div>
    <input type="text" v-model="input_one">
    <component-two :secondValue.sync="input_two"></component-two>
  </div>
</template>

<script>
  import ComponentTwo from 'component-two.vue'

  export default {
    name: "component-one",
    components: {
      ComponentTwo
    },
    data() {
      return {
        input_one: 'Hello from ComponentOne',
        input_two: ''
      }
    }
  }
</script>

component-two.vue:

<template>
  <div>
    <input type="text" v-model="input_two">
  </div>
</template>

<script>
  export default {
    name: "component-two",
    data() {
      return {
        input_one: 'Hello from ComponentTwo',
        input_two: ''
      },
      watch: {
        input_two : function(val){
          this.$emit('update:secondValue', val)
        }
      }
    }
  }
</script>
2
El Danielo