I get how to pass data from parent to child with props in a situation like:
<template>
<div>
<div v-for="stuff in content" v-bind:key="stuff.id">
<ul>
<li>
{{ stuff.items }}
</li>
</ul>
</div>
</div>
</template>
<script>
export default {
name: stuff,
props: ['content'],
data () {
return {
}
}
}
</script>
And then bind the data to the component in the parent component like,
<template>
<div>
<stuff v-bind:content="stuffToPass"></stuff>
</div>
</template>
<script>
import stuff from './stuff.vue';
export default {
data () {
return {
stuffToPass: [
{id: 1, items: 'foo'},
{id: 2, items: 'bar'},
{id: 3, items: 'baz'}
]
}
},
components: {
stuff
}
}
</script>
But say I have the root component, and I want to pass data to the stuff component, like in the above, but when I have a number of other components like parent > x > y > stuff , and it's still the stuff component that will ultimately be receiving that data, I don't know how to do that.
I heard of provide/inject, but I'm not sure that's the appropriate use, or at least I couldn't get it working.
Then I tried passing props, but then I found myself trying to bind a prop to a component to pass as a prop to a child component and that doesn't sound right, so then I just re-wrote my components in the 'stuff' component, but I feel that's probably re-writing way to much code to be close to reasonable.
there are a few possibilities to pass data parent > x > y > stuff
below, a simple example on how to implement the event bus:
// src/services/eventBus.js
import Vue from 'vue';
export default new Vue();
the code from where you want to emit the event:
// src/components/parent.vue
<script>
import EventBus from '@/services/eventBus';
export default {
...
methods: {
eventHandler(val) {
EventBus.$emit('EVENT_NAME', val);
},
},
...
};
</script>
the code for where you want to listen for the event:
// src/components/stuff.vue
<script>
import EventBus from '@/services/eventBus';
export default {
...
mounted() {
EventBus.$on('EVENT_NAME', val => {
// do whatever you like with "val"
});
},
...
};
</script>
Use watchers or computed properties https://v2.vuejs.org/v2/guide/computed.html
const Stuff = Vue.component('stuff', { props: ['content'], template: `<div> <div v-for="stuff in content" v-bind:key="stuff.id"> <ul> <li> {{ stuff.items }} </li> </ul> </div> </div>` }); const Adapter = Vue.component('adapter', { components: { Stuff }, props: ['data'], template: `<div> <Stuff :content="newData"/> </div>`, data() { return { newData: [] }; }, created() { this.changeData(); }, watch: { data: { deep: true, handler: function() { this.changeData(); } } }, methods: { changeData() { this.newData = JSON.parse(JSON.stringify(this.data)); } } }); const app = new Vue({ el: '#app', components: { Adapter }, data() { return { stuffToPass: [ { id: 1, items: 'foo' }, { id: 2, items: 'bar' }, { id: 3, items: 'baz' } ] }; }, methods: { addItem() { this.stuffToPass.push({ id: this.stuffToPass.length + 1, items: 'new' }); } } });
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.1/vue.js"></script> <div id="app"> <button @click="addItem">Add</button> <Adapter :data="stuffToPass"/> </div>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.