Reputation: 903
I have a few class based Vue.js components with properties, that I want to render dynamically. The components are simple, for example the following.
<template>
<b-alert :show="true">
{{$t(messageId)}}
</b-alert>
</template>
<script lang="ts">
import {Vue, Component, Prop} from "vue-property-decorator";
import i18n from "../../i18n";
@Component({
i18n
})
export default class UserErrorNotification extends Vue {
@Prop() messageId!: string
}
</script>
The components are rendered dynamically in a different component.
<template>
<div id="notification-area">
<div v-for="(notificationComponent, index) in notifications" :key="index">
<component :is="notificationComponent"/>
</div>
</div>
</template>
<script lang="ts">
import {Component, Inject, Vue} from "vue-property-decorator";
import {BAlert} from "bootstrap-vue";
import {Notification} from "@/Notification";
import InfoNotification from "@/components/notifications/InfoNotification.vue";
@Component({
components: {
InfoNotification,
}
})
export default class NotificationArea extends Vue {
@Inject('eventBus') private eventBus!: Vue;
notifications = [] as Array<Vue>;
notificationToComponent(notification: Notification): Vue {
if (notification.type == "success") {
let notificationComponent;
/* Somehow instantiate and fill in Props */
return notificationComponent
} else {
throw new Error("Unknown Notification Type: " + notification.type)
}
}
created() {
this.eventBus.$on('notification', (notification: Notification) => {
this.notifications.push(this.notificationToComponent(notification));
})
}
I know that $options
gives me an Options Object that can be rendered, but the message (property of the InfoNotification component) is always empty.
I already tried calling the constructor of the Component and assigning to the property and passing the propsData argument to the constructor. Neither filled the props of the component. Is there any way to do this?
Upvotes: 0
Views: 873
Reputation: 537
You actually never pass props in your code. Additionally i would suggest to not build an array of components inside your script. Passing of properties should also be done in your template instead.
If you want to pass multiple props as an object use the v-bind attribute for example:
<component v-bind="propsObject" />
The object should look like this:
{
messageId: "hello world"
}
However like i've said its not good practice to build components in your script.
Try this:
<template>
<div id="notification-area">
<div v-for="(notification, index) in notifications" :key="index">
<InfoNotification :messageId="notification.messageId"/>
</div>
</div>
</template>
<script lang="ts">
import {Component, Inject, Vue} from "vue-property-decorator";
import {BAlert} from "bootstrap-vue";
import {Notification} from "@/Notification";
import InfoNotification from "@/components/notifications/InfoNotification.vue";
@Component({
components: {
InfoNotification,
}
})
export default class NotificationArea extends Vue {
@Inject('eventBus') private eventBus!: Vue;
notifications = [] as Array<Notification>;
created() {
this.eventBus.$on('notification', (notification: Notification) => {
this.notifications.push(notification);
})
}
}
</script>
Im just assuming that your 'Notification' object has a property called messageId here. You could, of course, change that or just pass the whole notification object as a prop.
Upvotes: 1