如何在ListView中使用动态组件

时间:2019-02-09 03:16:03

标签: vue.js nativescript nativescript-vue

我试图用包含模板的模板填充NativeScript-Vue ListView,这些模板的类型事先不知道。例如,此代码不起作用,因为NativeScript没有'component'元素,但这暗示了我要完成的工作:

<ListView for="component in components">
    <v-template>
        <component :is="component" />
    </v-template>
</ListView>

computed: {
    components () {
        return ['Label', 'Button'];
    }
}

是的,我知道您可以在v模板中使用if =“”,但是在这种情况下,我不提前知道需要在ListView中加载哪些组件。就我而言,我正在插件中加载全局组件,这些组件将在ListView中引用。

2 个答案:

答案 0 :(得分:0)

您的模板不能是动态的,这就是使用ListView的全部目的-使其保持静态,因此可以根据需要重用它们。如果您希望基于数据查看不同的组件,则必须使用多个模板。

Read more on docs.

答案 1 :(得分:0)

感谢@Manoj。这些明智的话让我想到,模板不能是动态的,但v模板的内容可以是动态的。也许不适合所有人,但是这段代码对我有用:

// 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>