web-dev-qa-db-fra.com

Comment effectuer une liaison de données bidirectionnelle entre parents et petits-enfants dans Vue.js

J'ai rencontré un problème, je le résous par des cookies mais je veux résoudre le problème sans cookies. J'ai un composant qui a appelé app-header et Il a un autre composant qui a appelé outmodal. Maintenant, ma première instance Vue nécessite le composant app-header.

var vue = new Vue({
    el : "html",
    data : {
        title       : "Site Title",
        description : "description of page",
        keywords    : "my keywords",
        view        : "home",
        login       : "login"
    },
    components:{
        "app-header" :require("../../components/header"),
        "app-footer" :require("../../components/footer"),
        "home"       :require("../../views/home")
    },
});

code d'en-tête d'application

var Vue     = require("vue");

Vue.partial("login",require("../../partials/login.html"));
Vue.partial("logged",require("../../partials/logged.html"));

module.exports = {
    template    : require("./template.html"),
    replace     : true,
    components  : {
        outmodal : require("../outmodal")
    },
    props : ['login']
}

code de outmodal

var Vue = require("vue");
Vue.partial("loginModal",require("../../partials/loginModal.html"));

module.exports = {
    template    : require("./template.html"),
    replace     : true,
    props       : ['name'],
    data        : function () {
            return  {
                userLogin : { mail  :   "", password    :   "", remember    :   ""}
            }

    },
    methods : {
        formSubmit : function(e){
                e.preventDefault();
                this.$http.post("http://example.com/auth/login",{ "email": this.userLogin.mail , "password": this.userLogin.password },function(data,status,request){
                    $.cookie("site_token",data.token,{expires : 1})
                }).error(function(data,status,request){

                });

        }
    }, ready  : function(){
        console.log("it works")
    }
}

Dans le composant outmodal, je connecte l'API et je vérifie la connexion.Si la connexion réussit, je veux changer la valeur de la variable de connexion dans mon Vue instance. J'utilise un pack Web pour construire tous les besoins. Je ne sais donc pas comment puis-je lier des données entre ces fichiers.

Comment puis-je le résoudre? je

24
Kamuran Sönecek

La meilleure solution que j'ai trouvée

Pour 0,12

http://012.vuejs.org/guide/components.html#Inheriting_Parent_Scope

pour 1.0

http://v1.vuejs.org/guide/components.html#Parent-Child-Communication

pour 2.0

https://vuejs.org/v2/guide/components.html#Composing-Components (utilisez des accessoires pour lier des données à sens unique du parent à l'enfant)

17
Kamuran Sönecek

Il existe plusieurs façons de le faire, et certaines sont mentionnées dans d'autres réponses:

  1. Utilisez accessoires sur les composants
  2. Utilisez attribut v-model
  3. Utilisez le modificateur de synchronisation
  4. Utilisez Vuex

Pour les liaisons bidirectionnelles, gardez à l'esprit que cela peut provoquer une chaîne de mutations difficiles à maintenir, citée dans la documentation:

Malheureusement, une véritable liaison bidirectionnelle peut créer des problèmes de maintenance, car les composants enfants peuvent muter le parent sans que la source de cette mutation soit évidente à la fois chez le parent et l'enfant.

Voici quelques détails sur les méthodes disponibles:

1.) Utilisez des accessoires sur les composants

Les accessoires sont faciles à utiliser et sont le moyen idéal pour résoudre les problèmes les plus courants.
En raison de comment Vue observe les changements toutes les propriétés doivent être disponibles sur un objet ou elles ne seront pas réactives. Si des propriétés sont ajoutées après = Vue a fini de les rendre observables 'set' devra être utilisé.

 //Normal usage
 Vue.set(aVariable, 'aNewProp', 42);
 //This is how to use it in Nuxt
 this.$set(this.historyEntry, 'date', new Date());

L'objet sera réactif pour le composant et le parent:

Si vous passez un objet/tableau comme accessoire, il se synchronise automatiquement dans les deux sens - changez les données chez l'enfant, elles sont changées dans le parent.

Si vous passez des valeurs simples (chaînes, nombres) via des accessoires, vous devez utiliser explicitement le . Sync modifier

Comme cité dans -> https://stackoverflow.com/a/35723888/1087372

2.) Utilisez l'attribut v-model

L'attribut v-model est un sucre syntaxique qui permet une liaison bidirectionnelle facile entre le parent et l'enfant. Il fait la même chose que le modificateur de synchronisation, mais il utilise un accessoire spécifique et un événement spécifique pour la liaison

Cette:

 <input v-model="searchText">

est le même que celui-ci:

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

Où l'hélice doit être valeur et l'événement doit être entrée

3.) Utilisez le modificateur de synchronisation

Le modificateur de synchronisation est également du sucre syntaxique et fait la même chose que le modèle v, juste que les noms des accessoires et des événements sont définis par ce qui est utilisé.

Dans le parent, il peut être utilisé comme suit:

 <text-document v-bind:title.sync="doc.title"></text-document>

De l'enfant, un événement peut être émis pour informer le parent de tout changement:

 this.$emit('update:title', newTitle)

4.) Utilisez Vuex

Vuex est un magasin de données accessible à partir de tous les composants. Les modifications peuvent être souscrites.

En utilisant le magasin Vuex, il est plus facile de voir le flux des mutations de données et elles sont explicitement définies. En utilisant vue developer tools , il est facile de déboguer et de restaurer les modifications apportées.

Cette approche nécessite un peu plus de détails, mais si elle est utilisée tout au long d'un projet, elle devient un moyen beaucoup plus propre de définir comment les modifications sont apportées et d'où.

Voir le guide de démarrage

4
SanBen

j'ai trouvé que celui-ci était plus précis. https://vuejs.org/v2/guide/components.html#sync-Modifier uniquement dans 2.3.0+ tho. et honnêtement, ce n'est pas encore assez bon. devrait simplement être une option facile pour la liaison de données "bidirectionnelle". donc aucune de ces options n'est bonne.

essayez plutôt d'utiliser vuex. ils ont plus d'options à cette fin. https://vuex.vuejs.org/en/state.html

2
Martian2049