2017-10-08 220 views
0

我正在製作一個表單生成器,它使用輸入字段,按鈕等組件。我希望能夠根據我傳遞給它的選項生成表單。我不能讓它渲染組件。如何在Vue JS中動態地呈現組件?

我試圖返回純HTML但不會呈現組件。

我把從我Home.vue模板的形式產生,我想有一個選項對象的形式是這樣的:

options: { 
    name: { 
     type: 'input', 
     label: 'Name' 
    }, 
    submit: { 
     type: 'button', 
     label: 'Send' 
    } 
} 

模板:

<template> 
    <form-generator :options="options"></form-generator> 
</template> 

在表單生成器組件我已經嘗試了多種東西,如:

<template> 
    {{ generateForm(this.options) }} 
    // ... or ... 
    <div v-html="generateForm(this.options)"></div> 
</template> 

我包括所有組件,如:

import { 
    FormButton, 
    FormInput 
} from './FormComponents' 

現在最後一部分是我如何使FormInput呈現?

這不工作,因爲它的字面輸出HTML:

methods: { 
    generateForm(options) { 

    // .. do stuff with options .. 
    var form = '<form-input />' 

    return form 
    } 
} 

回答

4

Vue公司有一個非常簡單的方法生成動態組件:

<component :is="dynamicComponentName"></component> 

因此,我建議您將選項定義爲arr唉,並設置類型爲組件名稱:

options: [ 
    { 
     type: 'FormInput', 
     propsData: {label: 'Name'} 
    }, 
    { 
     type: 'FormButton', 
     propsData: {label: 'Send'} 
    } 
] 

然後用它的形式產生這樣的:

<component :is="option.type" v-for="option in options"></component> 

您也可以通過屬性,你會傳遞給螞蟻等成分,但因爲它是動態的,每個部件都有一組不同性質的我會通過它作爲一個對象和每一個部件將訪問它需要的數據:

<component :is="option.type" v-for="option in options" :data="option.propsData"></component> 

UPDATE

由於您沒有成分的控制它需要多一點操作:

對於需要文本中的每個組成部分,在選項中添加文本屬性:

options: [ 
     { 
      type: 'FormInput', 
      propsData: {label: 'Name'} 
     }, 
     { 
      type: 'FormButton', 
      text: 'Send', 
      propsData: {label: 'Send'} 
     } 
    ] 

然後只用它的分量:

<component :is="option.type" v-for="option in options">{{option.text}}</component> 

對於路過的屬性,我認爲你可以使用v-綁定通過它,然後它會自動解構它們,所以如果按鈕接受2個道具:rounded, color 的選項看起來像:

{ 
    type: 'FormButton', 
    text: 'Button', 
    propsData: {rounded: true, color: '#bada55'} 
} 

,然後組件:

<component :is="option.type" v-for="option in options" v-bind="option.propsData">{{option.text}}</component> 
+0

這可以工作,如果我直接控制組件。我正在使用Quasar Framework atm。而對於一個按鈕,您需要在文本之間放置文本,如下所示:http://quasar-framework.org/components/button.html#Basic-Usage ...還可以接受一些自定義屬性,如「圓」等等。使用你的例子意味着我需要包裝框架的每一個組件,這取決於他們需要什麼作爲輸入。在這個用例中有更簡單的方法嗎? – John

+0

更新了答案 – Tomer

+0

謝謝,這似乎工作。最後一個問題,你將如何傳遞「@click」和「v-bind」之類的東西? – John

0

您可以通過模板您的選擇進行迭代,並檢查一個選項類型:

<template> 
    <div v-for="option in options"> 
    <form-input v-if="option.type === 'input'"></form-input> 
    <form-button v-else-if="option.type === 'button'"></form-button> 
    </div> 
</template> 
+0

我不想做這種方式,因爲我無法控制以何種方式呈現組件。 – John

+0

我想你可以複製選項數組並根據需要對其進行排序,然後在模板中使用排序的選項。 –