Reputation: 10067
I have a component who initialized like this
<custom :opts="{map: false}"></custom>
and there is HTML similar to this
<template id="custom">
<div v-if="opts.map">
I'm awesome
</div>
<button v-on:click="show"></button>
</template>
where
function show(){
this.opts = {map:true} // (1) <-- This is working and I could see hidden div
this.opts.map = true // (2) <-- For some reason not working
Vue.set(this.opts, 'map', true) // (3) <-- Still not working
}
So my question is why variant 2 doesn't work and what should I change to make my control react to value reset on a button click. Or a proper explanation why (1) is working, but (2) isn't - also will be accepted as an answer.
Upvotes: 2
Views: 749
Reputation: 14043
The real problem with the code (all 3 versions) is changing a component's property from within a component. In idiomatic Vue, only the parent should change properties. If a component needs to effect a change, it should emit an event to the parent and let the parent make the necessary changes. Otherwise, there is ambiguity in which component "owns" the property.
All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around.
Sending Messages to Parents with Events
Upvotes: 1
Reputation: 686
Can be off base here but I believe this happens because in vue component props
are not reactive, so their objects are not being observed in depth. Or rather they are "a little bit reactive", reassigning the root prop does cause the DOM update but is not expected to be done manually and you'll see a warning when doing such on development build:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "..."
And for as why props are not completely reactive in the first place: https://v2.vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow
To work around the whole issue you must pass any necessary props to the component data
and if those props were passed as nested objects you might also want to completely avoid mutating them from within the component since it will propagate to the parent which, unless clearly mentioned, can be a source of bad news.
Upvotes: 0