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>
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.
Ist die übergeordnete oder eine gleichgeordnete Komponente vom Zustand abhängig?
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.
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()
},
...
},
...
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
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;
}
}
}
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>
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>