谢谢@Manoj。那些明智的话让我想到,模板不能是动态的,但 v-template 的内容可以。也许不适合所有人,但这段代码对我有用:
// App.vue
<template>
<Page>
<ActionBar title="Welcome to NativeScript-Vue!"/>
<GridLayout columns="*" rows="400,*">
<ListView ref="lv" for="item in items">
<v-template>
<v-component :type="item.type" :options="item.options" />
</v-template>
</ListView>
</GridLayout>
</Page>
</template>
<script lang="ts">
import Vue from 'nativescript-vue'
import { Component } from 'vue-property-decorator'
import VComponent from './VComponent.vue'
@Component({
components: {
VComponent
}
})
export default class App extends Vue {
get items () {
return [
{type: 'Label', options: [{key: 'text', value: 'I am a Label'}, {key: 'color', value:'red'}] },
{type: 'Button', options: [{key: 'text', value:'I am a Button!'}]}
]
}
}
</script>
// VComponent.vue
<template>
<StackLayout ref="myLayout">
</StackLayout>
</template>
<script lang="ts">
import Vue from 'nativescript-vue'
import { Component, Prop } from 'vue-property-decorator'
import { StackLayout } from 'tns-core-modules/ui/layouts/stack-layout'
import { Label } from 'tns-core-modules/ui/label'
import { Button } from 'tns-core-modules/ui/button'
const classByClassName = {
'Label': Label,
'Button': Button
}
@Component
export default class CoolTemplate extends Vue {
@Prop() type!: string;
@Prop() options;
mounted () {
if (this.type) {
const myLayout = <StackLayout>((<Vue>this.$refs.myLayout).nativeView)
const component = new classByClassName[this.type]
for (var i = 0; i< this.options.length; i++) {
const option = this.options[i];
component[option.key] = option.value
}
myLayout.addChild(component)
}
}
}
</script>