Reputation: 502
Here is my code under computed
computed: {
display: {
get() {
return this.display
},
set(newValue) {
this.display = newValue
}
}
},
i am trying to update the value of computed from a function under model
async submit() {
this.display = false;
}
while submit function runs, i get below error on console
Uncaught (in promise) RangeError: Maximum call stack size exceeded
Upvotes: 0
Views: 1423
Reputation: 29092
When you write this.display = newValue
in the set
it will just cause the set
to be called again, going round and round in a loop.
To wrap a prop in a computed property you need to give it a different name. Further, the set
should be emitting an event so that the parent component can update the data. You can't do it directly within the current component.
The example below uses the sync
modifier but you could use a separate event listener if you prefer.
const Child = {
template: `<input v-model="displayModel">`,
props: ['display'],
computed: {
displayModel: {
get () {
return this.display
},
set (display) {
this.$emit('update:display', display)
}
}
}
}
new Vue({
el: '#app',
components: {
Child
},
data () {
return {
parentDisplay: 'hello'
}
}
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script>
<div id="app">
<p>{{ parentDisplay }}</p>
<child :display.sync="parentDisplay"></child>
</div>
You could also just emit
the event directly rather than modifying the property at all, skipping the computed property altogether. i.e. Replace this.display = false;
with an $emit
.
Alternatively, if the prop is used only to set the initial value of the property then you should just copy it across to a data
property when the component is first created:
props: ['display'],
data () {
return {
internalDisplay: this.display
}
}
You can then set the value of internalDisplay
directly.
Upvotes: 3