I'm using Vue2 and TypeScript and I want to pass multiple properties to a Vue component in code. The component is not mounted via a template but in code. I dynamicly create an element in the DOM and later mount the component on the element.
Vue2 component 'ActivityStream':
<template>
<div id="activity-stream">
<md-list>
<activity-list-item v-for="item in items" :key="item.getId()" :activity="item" :language="language"/>
</md-list>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { Activity } from "models/Activity";
import { Component, Prop } from "vue-property-decorator";
import MdList from "vue-material/dist/components/MdList";
import MdIcon from "vue-material/dist/components/MdIcon";
import ActivityListItem from "components/ActivityListItem.vue";
Vue.use(MdList);
Vue.use(MdIcon);
@Component({
components: {
ActivityListItem
}
})
export default class ActivityStream extends Vue {
name: "activity-stream";
@Prop()
count: number;
@Prop({ type: LanguageDefinitionNL })
language: ILanguageDefinition;
items: Activity[] = new Array<Activity>();
</script>
Create and mount the element dynamicly in code (Typescript):
stream = document.createElement('activity-stream');
stream.setAttribute("id", "stream");
stream.setAttribute("count", "20");
var ActivityStreamClass = Vue.extend(ActivityStream);
this._activityStream = new ActivityStreamClass();
this._activityStream.$mount('#stream');
First of all the 'count' attribute is not picked up by the Vue component and turns out to be undefined. Secondly I don't know how to pass a non-static property like a data model in code (e.g. the 'language' property in this example). Can it be passed in the constructor of the Vue (e.g. new ActivityStreamClass({..})
) or should I make my own setter methods on the component class?
ActivityStream.setCount(count: number))
As I didn't find any standard Vue(2) way for doing this I just added methods to my component which kind of looks logical to do:
<template>
<div id="activity-stream">
<md-list>
<activity-list-item v-for="item in items" :key="item.getId()" :activity="item" :language="language"/>
</md-list>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { Activity } from "models/Activity";
import { Component, Prop } from "vue-property-decorator";
import MdList from "vue-material/dist/components/MdList";
import MdIcon from "vue-material/dist/components/MdIcon";
import ActivityListItem from "components/ActivityListItem.vue";
import { LanguageDefinitionNL } from "tools/i18n/LanguageDefinitionNL";
import { ILanguageDefinition } from "tools/i18n/interfaces/ILanguageDefinition";
Vue.use(MdList);
Vue.use(MdIcon);
@Component({
components: {
ActivityListItem
}
})
export default class ActivityStream extends Vue {
name: "activity-stream";
@Prop()
count: number;
@Prop({ type: LanguageDefinitionNL })
language: ILanguageDefinition;
items: Activity[] = new Array<Activity>();
public setCount(count: number): void {
this.count = count;
}
public setLanguage(language: ILanguageDefinition): void {
this.language = language;
}
public addItem(activity: Activity): void {
// Add new item at the top of the list
this.items.unshift(activity);
}
}
</script>
And when I'm using the component from plain Typescript/Javascript I do the following:
var ActivityStreamClass = Vue.extend(ActivityStream);
this._activityStream = new ActivityStreamClass();
this._activityStream.setCount(10);
this._activityStream.setLanguage(language);
this._activityStream.$mount('#stream');
Enjoy!