Имея некоторое время, чтобы обдумать это, я должен заключить, что мое раздражение вызвано необходимостью введения промежуточного компонента 'f-dummy' просто для того, чтобы я смог захватить функцию рендеринга Vue, которую я мог затем передать в pojo.
Что я изменил сейчас, так это то, что я отображаю сам список , используя дескриптор render (createElement) (или 'h') нижнего уровня, который затем я могу передать потомку без необходимости прибегать к промежуточному компоненту .
Вот новый код, во-первых, я определяю классы ES6 (обратите внимание, что Color, Orange, Blue являются только примерами):
export class Colour {
public colour: string = "";
constructor(colour: string) {
this.colour = colour;
}
render(h: any) {
return h("h1", "Error - please provide your own implementation!");
}
}
export class Orange extends Colour {
constructor() {
super("orange");
}
public getStyle() {
return {
class: ['example-class'],
style: { backgroundColor: this.colour, border: '3px solid red' }
}
}
render(h: any) {
return h('h4', this.getStyle(), "This is my colour: " + this.colour)
}
}
export class Blue extends Colour {
private _isDisabled = true;
constructor(disabled: boolean) {
super("lightblue");
this._isDisabled = disabled;
}
render(h: any) {
return h('div',
[
h('h4', {
class: ['example-class', { 'is-disabled': this._isDisabled }],
style: { backgroundColor: this.colour }
}, "Hello, I am " + this.colour)
]
)
}
}
Чтобы отобразить список, я теперь делаю это:
Vue.component("fusion-toolbar", {
props: ["items"],
render(h: any) {
return h('div', this.items.map(function (item: any) {
return item.render(h);
}))
}
});
Теперь я могу просто добавить оранжевый или синий 'pojo' экземпляры в мой список, и они будут отображаться правильно.См. Содержание App.vue ниже:
<template>
<div id="app">
<fusion-toolbar v-bind:items="myitems"> </fusion-toolbar>
</div>
</template>
<script lang="ts">
import Vue from "vue";
import { Colour, Orange, Blue } from "./components/DropDownItem";
export default Vue.extend({
name: "app",
data: function() {
return {
myitems: [] as Colour[]
}
},
mounted() {
this.myitems.push(new Orange());
this.myitems.push(new Blue(false));
this.myitems.push(new Blue(true));
}
});
</script>
<style lang="scss">
#app {
font-family: "Avenir", Helvetica, Arial, sans-serif;
text-align: center;
}
.example-class {
width: 250px;
padding: 3px;
}
.is-disabled {
color: gray;
}
</style>
Вот как выглядит образец:
![enter image description here](https://i.stack.imgur.com/vNDvc.png)
Очень аккуратно.Я понимаю, что могу использовать плагин Babel для использования JSX вместо низкоуровневого рендеринга Vue, но я вполне наслаждаюсь мощью, которую он мне дает!