コンポーネント内のプロパティを変更する方法について少し混乱しています。次のコンポーネントがあるとします。
{
props: {
visible: {
type: Boolean,
default: true
}
},
methods: {
hide() {
this.visible = false;
}
}
}
動作しますが、次の警告が表示されます。
親コンポーネントが再レンダリングされるたびに値が上書きされるため、プロップを直接変更しないでください。代わりに、小道具の値に基づいてデータまたは計算されたプロパティを使用します。変化するプロップ: "visible"(コンポーネントにあります)
今、私はこれを処理する最良の方法が何であるか疑問に思っています、明らかにvisible
プロパティはDOMでコンポーネントを作成するときに渡されます:<Foo :visible="false"></Foo>
your fiddle のコードを参照する
どういうわけか、2つではなく州が住む1つの場所を決める必要があります。 Alert
に入れるのが適切か、ユースケースの親に入れるのが適切かはわかりませんが、選択する必要があります。
親または兄弟コンポーネントは状態に依存しますか?
まれに、組み合わせが必要な場合があります。おそらく、親と子の両方に子を隠す機能を与えたいと思うでしょう。次に、親と子の両方に状態があるはずです(そのため、子の中で子の小道具を編集する必要はありません)。
たとえば、次の場合に子を表示できます:visible && state_visible
、ここでvisible
は小道具から派生し、親の状態の値を反映し、state_visible
は子の状態からのものです。
これがあなたが望む行動であるかどうかはわかりませんが、 ここはフィドルです 。子をクリックすると、親コンポーネントのtoggleAlert
を実際に呼び出したいだけだと思います。
最新のコメントを読んだ後、親のアラートを表示/非表示するロジックを持っていることに懸念があるようです。したがって、次のことをお勧めします。
親
# template
<alert :alert-visible="alertVisible"></alert>
# script
data () {
alertVisible: false,
...
},
...
次に、子アラートで、小道具の値を$ watchし、すべてのロジックをアラートに移動します。
子(アラート)
# 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()
},
...
},
...
小道具がこの子コンポーネントにのみ有用な場合、子にprop
のような_initialVisible
とdata
のようなmutableVisible
、およびcreated
フック(コンポーネントのデータ構造がアセンブルされるときに呼び出されます)では、単にthis.mutableVisible = this.initialVisible
。
プロップが親コンポーネントの他の子と共有されている場合、それを親のdata
にする必要がありますすべての子供。次に、子でthis.$emit('visibleChanged', currentVisible)
を変更して親にvisible
を変更するよう通知します。親のテンプレートで、<ThatChild ... :visibleChanged="setVisible" ...>
を使用します。ガイドをご覧ください: http://vuejs.org/v2/guide/components.html
誰かを助けるために、私は同じ問題に直面していました。 v-model = ""内の変数をprops配列からデータに変更しました。小道具とデータの違いを覚えておいてください、私の場合、それを変更するのは問題ではありませんでした。
例えば。:
<v-dialog v-model="dialog" fullscreen hide-overlay transition="dialog-bottom-transition">
前:
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;
}
}
}
後:
export default {
data: function () {
return {
dialog: false
}
},
props: {
notifications: false,
sound: false,
widgets: false
},
methods: {
open: function () {
var vm = this;
vm.dialog = true;
}
}
}
Vue.jsコンポーネントドキュメント によると:
親プロパティが更新されると、それは子に流れますが、その逆ではありません。それで、何かが起こったとき、どのように親に連絡しますか?これがVueのカスタムイベントシステムの出番です。
子の$emit('my-event)
を使用して、親にイベントを送信します。 v-on:my-event
(または@my-event
)を使用して、親内の子宣言でイベントを受け取ります。
作業例:
// 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>
ハックのように見えて、単一のデータソースの概念に違反しているかもしれませんが、その作業)このソリューションはローカルプロキシ変数を作成し、小道具からデータを継承しています。次にプロキシ変数を使用します。
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);
}
});
}
}
});
コンポーネントを使用して小道具を渡す
<vote :like="item.vote_like" :dislike="item.vote_dislike" :item="item"></vote>