I am writing VueJS (2.5.22) application using Typescript and trying to add component dynamically at run-time. I ran into two issues with Typescript. Adding child component as named slots and subscribing to emit event from child components. I was able to work around slots by appending child component, however i would like to use named slots. Any input on slot is appreciate.
I am still trying to get second issue resolved of parent component subscribing to child event and updating property in parent component.
The child component is going to emit "update-value". How do i subscribe to this event on parent component dynamically?
Thanks,
Please create tag for: vuejs-component vuejs-dynamic-component vuejs-typescript vuejs-emit
parent component adding dynamically at run-time in created method
<div>
<p>Dynamic components</p>
<div ref="controls"></div>
</div>
export default class ParentComponent extends Vue {
public $refs: Vue['$refs'] & {
controls: HTMLElement
}
public $slots: Vue['$slots'] & {
TextBox: TextBox
}
vuejs created method
--------------------
const labelControlContainerClass = Vue.extend(LabelControlContainer)
const textBoxClass = Vue.extend(TextBox)
const fields = table.fields
for (const key in fields) {
if (fields.hasOwnProperty(key)) {
const element = fields[key]
if (element.fieldType === 'Char') {
const textBoxInstance = new textBoxClass({
// props
propsData: {
value: '',
placeholder: element.translatedCaption,
name: key
},
// how to subscript to "update-value" event???
})
textBoxInstance.$mount()
const instance = new labelControlContainerClass({
// props
propsData: {
caption: element.translatedCaption,
bold: false
},
})
instance.$mount()
instance.$el.appendChild(textBoxInstance.$el) // add child component, try adding named slots, but didn't work
this.$refs.controls.appendChild(instance.$el)
}
}
}
}
label component with slot. named slot didn't worked
<template>
<div class="controlContainer" :class="{vertial: labelTop}">
<span v-bind:class="{bold: bold}" class=".controlContainer__cisLabel">{{caption}}</span>
<slot name='control'></slot>
<slot></slot>
</div>
</template>
<script lang='ts'>
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
@Component({
})
export default class LabelControlContainer extends Vue {
@Prop({ type: String, default: '' }) public caption: string
@Prop({ type: Boolean, default: true }) public bold: boolean
@Prop({ type: Boolean, default: false }) public labelTop: boolean
}
</script>
child component that is going to added to slot and emit on value change
export default class TextBox extends Vue {
@Prop({ type: String, default: 'placeholder text' }) public placeholder: string
@Prop({ type: Object, default: () => ({}) }) public attributes: any
@Prop({ type: Boolean, default: false }) public readonly: boolean
@Prop({ type: String, default: 'text' }) public mode: string
@Prop({ type: Boolean, default: true }) public isValid: boolean
@Prop({ type: String, default: '' }) public value: string
@Prop({ type: String, default: '' }) public name: string
@Prop({ type: Boolean, default: false }) public setFocus: boolean
private default = {}
private unlockable: boolean = this.readonly
private valueChanged(data: any): void {
this.$emit('update-value', data.value, this.name)
}
}