I created two components in Vue.js, the main one use a child component called NoteRenderer, which has a prop called data_exchange defined. I want to modify the prop from the main component when a button is clicked. I thought this code would work :
<template>
<div>
<h1>Study</h1>
<button @click="update_nra()">Change NodeRenderer text.</button>
</div>
<nra/>
<nrb/>
</template>
<script>
import NoteRenderer from '../components/NoteRenderer.vue'
export default {
components: {
'nra': NoteRenderer,
'nrb': NoteRenderer
},
methods: {
update_nra: function() {
this.nra.exchange_data = "new text";
}
}
}
</script>
But I get the runtime error Uncaught TypeError: this.nra is undefined. How should I manipulate the instance NoteRenderer instance nra in the update_nra() method ?
Try this way:
<template>
<div>
<h1>Study</h1>
<button @click="update_nra()">Change NodeRenderer text.</button>
</div>
<nra :exchange_data="exchange_data" />
<nrb/>
</template>
<script>
import NoteRenderer from '../components/NoteRenderer.vue'
export default {
data() {
return {
exchange_data: ''
}
},
components: {
'nra': NoteRenderer,
'nrb': NoteRenderer
},
methods: {
update_nra: function() {
this.exchange_data = "new text";
}
}
}
</script>
Vue.component('nra', {
template: `
<div>
{{exchange_data}}
</div>
`,
props: ['exchange_data']
})
new Vue({
el: '#demo',
data() {
return {
exchange_data: 'old text'
}
},
methods: {
update_nra: function() {
this.exchange_data = "new text";
}
}
})
Vue.config.productionTip = false
Vue.config.devtools = false
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<template>
<div>
<h1>demo</h1>
<button @click="update_nra()">Change NodeRenderer text.</button>
</div>
<nra :exchange_data="exchange_data" />
</template>
</div>
I see the other answer that has the code, but not an explanation, so I try to provide one.
In Vue, the properties are something you pass to a Component, so, in your main component you should have a data variable, where you change the value and then you have to bind that variable as a property of the sub-component.
It is not a good practice to access the internals of another component, instead you should follow the Vue API.
Note that the properties should not be changed from inside a component, instead the code that passed that property is owner of the changes.
This way the flow of the data is much clear and the code will have less bug and even with bugs it will be much easy to understand.