webentwicklung-frage-antwort-db.com.de

Vue.js Requisiten wechseln

Ich bin etwas verwirrt darüber, wie man Eigenschaften in Komponenten ändert. Nehmen wir an, ich habe die folgende Komponente:

{
    props: {
        visible: {
            type: Boolean,
            default: true
        }
    },
    methods: {
         hide() {
              this.visible = false;
         }
    }
} 

Obwohl es funktioniert, würde es folgende Warnung geben: 

Vermeiden Sie das direkte Mutieren einer Eigenschaft, da der Wert überschrieben wird, wenn die übergeordnete Komponente erneut gerendert wird. Verwenden Sie stattdessen eine Daten- oder berechnete Eigenschaft, die auf dem Wert der Eigenschaft basiert. Prop wird mutiert: "visible" (gefunden in Komponente)

Jetzt frage ich mich, wie Sie am besten damit umgehen können. Offensichtlich wird die visible -Eigenschaft beim Erstellen der Komponente im DOM übergeben: <Foo :visible="false"></Foo>

13
woutr_be

Verweis auf den Code in Ihre Geige

Irgendwie solltest du dich für one Ort entscheiden, damit der Staat leben kann, nicht zwei. Ich weiß nicht, ob es angemessener ist, es nur in der Variablen Alert oder nur in seinem übergeordneten Element für Ihren Anwendungsfall zu haben, aber Sie sollten einen auswählen.

Wie man entscheidet, wo der Staat lebt

Ist die übergeordnete oder eine gleichgeordnete Komponente vom Zustand abhängig?

  • Ja: Dann sollte es im Parent (oder in einer externen Zustandsverwaltung) sein.
  • Nein: Dann ist es einfacher, es im Zustand der Komponente selbst zu haben
  • Ein bisschen beides: Siehe unten

In einigen seltenen Fällen möchten Sie möglicherweise eine Kombination. Vielleicht möchten Sie Eltern und Kindern die Möglichkeit geben, das Kind zu verstecken. Dann sollten Sie den Status von Eltern und Kind haben (damit Sie nicht die Requisiten des Kindes in einem Kind bearbeiten müssen).

Kind kann beispielsweise sichtbar sein, wenn visible && state_visible, wobei visible von Requisiten kommt und einen Wert im Status des übergeordneten Objekts widerspiegelt, und state_visible vom Status des untergeordneten Objekts stammt.

Ich bin nicht sicher, ob dies das gewünschte Verhalten ist, aber hier ist eine Geige . Ich gehe davon aus, dass Sie tatsächlich die Variable toggleAlert der übergeordneten Komponente aufrufen möchten, wenn Sie auf das untergeordnete Element klicken.

11
ArneHugo

Nachdem Sie Ihre neuesten Kommentare gelesen haben, scheint es, dass Sie sich Sorgen machen, ob Sie die Warnmeldungen des übergeordneten Elements anzeigen oder ausblenden möchten. Daher würde ich folgendes vorschlagen:

Elternteil

# template
<alert :alert-visible="alertVisible"></alert>

# script
data () {
  alertVisible: false,
  ...
},
...

Bei der untergeordneten Warnung würden Sie $ den Wert der Requisite beobachten und die gesamte Logik in die Warnung verschieben:

Kind (Alarm)

# script
data: {
  visible: false,
  ...
},
methods: {
  hide () {
    this.visible = false
  },
  show () {
    this.visible = true
  },
  ...
},
props: [
  'alertVisible',
],
watch: {
  alertVisible () {
    if (this.alertVisible && !this.visible) this.show()
    else if (!this.alertVisible && this.visible) this.hide()
  },
  ...
},
...
4
GuyC

Wenn die Requisite nur für diese untergeordnete Komponente nützlich ist, geben Sie dem Kind eine prop wie initialVisible und eine data wie mutableVisible und im created-Hook (der beim Zusammenstellen der Datenstruktur der Komponente aufgerufen wird) einfach this.mutableVisible = this.initialVisible

Wenn die Eigenschaft von anderen untergeordneten Elementen der übergeordneten Komponente gemeinsam genutzt wird, müssen Sie sie als data der übergeordneten Komponente festlegen, um sie allen Kindern zur Verfügung zu stellen. Dann unterrichten Sie this.$emit('visibleChanged', currentVisible), um das übergeordnete Element zu benachrichtigen, um visible zu ändern. Verwenden Sie in der Vorlage des übergeordneten Elements <ThatChild ... :visibleChanged="setVisible" ...>. Sehen Sie sich den Leitfaden an: http://vuejs.org/v2/guide/components.html

3

Um jemandem zu helfen, stand ich vor demselben Problem. Ich habe gerade mein var in v-model = "" vom Requisiten-Array in Daten geändert. Denken Sie an den Unterschied zwischen Requisiten und Daten. In meinem Fall war das kein Problem bei der Änderung. Sie sollten Ihre Entscheidung belasten.

Z.B.:

<v-dialog v-model="dialog" fullscreen hide-overlay transition="dialog-bottom-transition">

Vor:

export default {
    data: function () {
        return {
            any-vars: false
        }
    },
    props: {
            dialog: false,
            notifications: false,
            sound: false,
            widgets: false
        },
    methods: {
        open: function () {
            var vm = this;

            vm.dialog = true;
        }
    }
}

Nach dem:

export default {
    data: function () {
        return {
            dialog: false
        }
    },
    props: {
            notifications: false,
            sound: false,
            widgets: false
        },
    methods: {
        open: function () {
            var vm = this;

            vm.dialog = true;
        }
    }
}
2
Marco

Gemäß der Vue.js-Komponente doc

Wenn die übergeordnete Eigenschaft aktualisiert wird, wird sie an das untergeordnete Element weitergeleitet, jedoch nicht umgekehrt. Wie kommunizieren wir also mit den Eltern, wenn etwas passiert? Hier kommt das benutzerdefinierte Ereignissystem von Vue ins Spiel.

Verwenden Sie $emit('my-event) vom untergeordneten Element, um ein Ereignis an das übergeordnete Element zu senden. Empfangen Sie das Ereignis für die untergeordnete Deklaration im übergeordneten Element mit v-on:my-event (oder @my-event). 

Arbeitsbeispiel:

// child

Vue.component('child', {
  template: '<div><p>Child</p> <button @click="hide">Hide</button></div>',
  methods: {
    hide () {
      this.$emit('child-hide-event')
    }
  },
})

// parent

new Vue({
  el: '#app',
  data: {
    childVisible: true
  },
  methods: {
    childHide () {
      this.childVisible = false
    },
    childShow () {
      this.childVisible = true
    }
  }
})
.box {
  border: solid 1px grey;
  padding: 16px;
}
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<div id="app" class="box">
  <p>Parent | childVisible: {{ childVisible }}</p>
  <button @click="childHide">Hide</button>
  <button @click="childShow">Show</button>
  <p> </p>
  <child @child-hide-event="childHide" v-if="childVisible" class="box"></child>
</div>

0

Vielleicht sieht es aus wie auf einem Hack und verstößt gegen das Konzept einer einzelnen Datenquelle, aber seine Arbeit. Diese Lösung erstellt lokale Proxy-Variablen und erbt Daten von Requisiten. Nächste Arbeit mit Proxy-Variablen.

Vue.component("vote", {
    data: function() {
        return {
            like_: this.like,
            dislike_: this.dislike,
        }
    },

    props: {
        like: {
            type: [String, Number],
            default: 0
        },
        dislike: {
            type: [String, Number],
            default: 0
        },
        item: {
            type: Object
        }
    },

    template: '<div class="tm-voteing"><span class="tm-vote tm-vote-like" @click="onVote(item, \'like\')"><span class="fa tm-icon"></span><span class="tm-vote-count">{{like_}}</span></span><span class="tm-vote tm-vote-dislike" @click="onVote(item, \'dislike\')"><span class="fa tm-icon"></span><span class="tm-vote-count">{{dislike_}}</span></span></div>',

    methods: {
        onVote: function(data, action) {
            var $this = this;
            // instead of jquery ajax can be axios or vue-resource
            $.ajax({
                method: "POST",
                url: "/api/vote/vote",
                data: {id: data.id, action: action},
                success: function(response) {
                    if(response.status === "insert") {
                        $this[action + "_"] = Number($this[action + "_"]) + 1;
                    } else {
                        $this[action + "_"] = Number($this[action + "_"]) - 1;
                    }
                },
                error: function(response) {
                    console.error(response);
                }
            });
        }
    }
});

komponente verwenden und Requisiten übergeben

<vote :like="item.vote_like" :dislike="item.vote_dislike" :item="item"></vote>
0
Vitaliy