0👍
✅
I could solve it via slot but I’ve still needed to use forceUpdate()
in the LayoutComponent…
However with the genericProps it’s good enough for my case.
Parent Template
<template v-slot:leftColumn >
<div v-for="(entry, index) in firstColumn" :key="`left_${index}`" >
<component :is="entry" :genericProps="entry.genericProps" />
</div>
</template>
<template v-slot:rightColumn>
<div v-for="(entry, index) in secondColumn" :key="`right_${index}`" >
<component :is="entry" :genericProps="entry.genericProps" />
</div>
</template>
Parent Code
This code is called via mounted()
or via watch when the async call from the API is finished.
createMetadataContent() {
let currentContent = this.currentMetadataContent;
const components = this.$options.components;
currentContent = this.mixinMethods_enhanceMetadataEntry(currentContent, this.cardBGImages);
if (currentContent && currentContent.title !== undefined) {
this.body = metaDataFactory.createBody(currentContent);
this.$set(components.MetadataBody, 'genericProps', this.body);
this.citation = metaDataFactory.createCitation(currentContent);
this.$set(components.MetadataCitation, 'genericProps', this.citation);
// a few more components and data here
this.firstColumn = [
components.MetadataBody,
// a few more components here
];
this.secondColumn = [
components.MetadataCitation,
// a few more components here
];
this.singleColumn = [
components.MetadataBody,
components.MetadataCitation,
// a few more components here
];
this.$forceUpdate();
}
}
TwoColumnLayout Template
<v-flex v-bind="firstColWidth" >
<v-layout column>
<slot name="leftColumn" />
</v-layout>
</v-flex>
<v-flex v-if="secondColumn" v-bind="secondColWidth" >
<v-layout column>
<slot name="rightColumn" />
</v-layout>
</v-flex>
TwoColumnLayout Code
updated() {
this.$children.forEach((child) => {
child.$forceUpdate();
});
},
Child Code
All child components have the genericProps object which is accessed via mixin method
props: {
genericProps: Object,
},
computed: {
title() {
return this.mixinMethods_getGenericProp('title');
},
id() {
return this.mixinMethods_getGenericProp('id');
},
description() {
return this.mixinMethods_getGenericProp('description');
},
}
Mixin method
mixinMethods_getGenericProp(propName) {
return this.genericProps[propName] ? this.genericProps[propName] : null;
},
0👍
I once had a similar situation where I had a dynamic <compnonent :is="currentComponent">
and solved it by storing a ‘childPayload’-attribute to my data and passed it as prop to the children. Whenever my payload changed, it got refreshed in the children.
<template>
<div>
<div class="btn btn-primary" @click="changePayload">Change Payload</div>
<component :is="isWhat" :payload="payload"></component>
</div>
</template>
<script>
export default {
name: "Test",
data() {
return {
isWhat: 'div',
payload: { any: 'data', you: 'want', to: 'pass'}
}
},
methods: {
changePayload() { // any method or api call can change the data
this.payload = { some: 'changed', data: 'here' }
}
}
}
</script>
Source:stackexchange.com