如何获取动态生成的VueJS组件进行渲染

时间:2017-05-15 14:54:13

标签: javascript vuejs2

我正在尝试动态地将组件添加到我的vue模板中。事情没有像预期的那样发生。

我有这个组件:

Vue.component('form-x-text', {
  delimiters: ["[[", "]]"],
  template: `
    <div v-if="_.indexOf(['text','email','tel','number','url','color'], fType) > 0" class="form-group" :class="{'has-error': errors.has(fName)}">
      <label :for="fId">[[fLabel]]</label>
      <input v-validate="{ rules: parsedRule }" class="form-control" :type="fType" :name="fName" :id="fId" data-vv-delay="700">
      <span class="field-error" v-show="errors.has(fName)"> [[ errors.first(fName) ]]</span>
    </div>
  `,
  props: {
    fType: {
      type: String,
      validation: function(value){
        return _.indexOf(['text','email','tel','number','url','color'], value) > 0
      },
      required: true
    },
    fName: {
      type: String,
      required: true
    },
    fId: null,
    fLabel: null,
    fRule: null
  },
  computed: {
    parsedRule: function(){
      console.log(this.fRule);
      return JSON.parse(this.fRule);
    }
  }
})


class FormX{
  constructor(){
    
  }
  
  static newForm(){
    return JSON.parse(`
    {
      "node": "root",
      "child": []
    }
    `)
  }
  
  static textInput(ftype, name, label, id, required = false){
    
    let emailR = false;
    
    if (ftype == 'email'){
      emailR = true;
    }
    
    return JSON.parse(
    `
      {
        "node": "element",
        "tag": "form-x-text",
        "attr": {
          "f-type": "${ftype}",
          "f-name": "${name}",
          "f-label": "${label}",
          "f-id": "${id}"
        }
      }
    `
    )
  }
  
}


var builder = new Vue({
  el: '#builder',
  delimiters: ["[[", "]]"],
  data: {
    blankTemplate: {
      node: 'root',
      child: [
        {
          node: 'element',
          tag: 'div',
          attr: { id: '1', class: 'foo'},
          child: []
    },
    workingTemplate: {
      content: {}
    },
    primaryButton: {},
    secondaryButton: {},
    bForm: null,
  },
  methods: {
    openFormDesigner: function(){
      
      $('#formDesignerModal').modal('show');
      this.primaryButton = {'show':false, 'text':'Save', 'spanstyle':'fa fa-floppy-o'};
      this.secondaryButton = {'show':true, 'text': 'Close'};
    },
    addToFormCanvas: function(ftype){
      if (!ftype){
        console.log("You need to provide the type of the Form element");
      }else if (ftype == 'email'){
        this.bForm.child.push(FormX.textInput('email', 'mail1','mail1','mail1'));
      }else if (ftype == 'text'){
        this.bForm.child.push(FormX.textInput('text', 'mail1','mail1','mail1'));
      }else if (ftype == 'number'){
        this.bForm.child.push(FormX.textInput('number', 'mail1','mail1','mail1'));
      }
      
    },
    jsonToHtml: function(jsono){
      return json2html(jsono);
    },
    getAttr: function(aobj){
      return aobj
    }
  },
  mounted: function(){
    $('#vwr-panel > iframe').contents().find('body').css({"margin":"0 auto", "background-color":"#fff"}).html(
        json2html(this.blankTemplate));
    
    
  },
  created: function(){
    this.bForm = FormX.newForm();
  },
  computed: {
    bFormHtml: function(){
      return json2html(this.bForm)
    }
  },
  filters: {
    capitalize: function(v){
      return _.toUpper(v);
    }
  }
})

当点击发生时,我基本上附加到我的vue实例中的数据对象。 然后我使用json2html将这个数据对象转换为“html”,它实际上是一个组件。

我希望该组件将被渲染,但是虽然我可以在检查器中看到它,但它不会渲染。

我正在使用<div v-html="bFormHtml"></div>

插入组件

1 个答案:

答案 0 :(得分:0)

您是否尝试过使用可变<component>标记?

HTML:

...
<component :is="componentId"></component>
...

的javascript:

...
data: {
    componentId: 'blank'
},
components: {
    'blank': {
        'template': '<div></div>'
    }
},
methods: {
    'updateComponent': function() {
        this.componentId = 'form-x-text'
    }
}
...

JsFiddle多个组件的示例。

我不确定它是否能与您拥有的完全一致,但它可能比尝试注入HTML更好。