Vue JS Component Dynamically

by WILLIAM CORREA

HTML

<div id="app">
  <select v-model="component">
    <option v-for="__component in components" :value="__component">
      {{ __component }}
    </option>
  </select>
  <hr>
  <component :is="component" v-bind="schema"></component>
  <button v-listen="events">Click</button>
</div>

Babel + JSX

Vue.component('f-input-text', Vue.extend({
  props: ['value'],
  template: '<div><input :value="value"/></div>'
}))

Vue.component('f-textarea', Vue.extend({
  props: ['value'],
  template: '<div><textarea :value="value"></textarea></div>'
}))

const bindEvents = (el, events) => {
  Object.keys(events).forEach(event => {
    el.addEventListener(event, events[event])
  })
}

const unbindEvents = (el, events) => {
  Object.keys(events).forEach(event => {
    el.removeEventListener(event, events[event])
  })
}

Vue.directive('listen', {
  bind (el, binding) {
  	this.$events = binding.value
    bindEvents(el, binding.value)
  },
  update(el, binding) {
  	unbindEvents(el, this.$events)
    bindEvents(el, binding.value)
  	this.$events = binding.value
  },
  unbind() {
  	unbindEvents(el, this.$events)
  }
})


new Vue({
  el: '#app',
  name: 'god',
  data: () => ({
    component: 'f-input-text',
    components: ['f-input-text', 'f-textarea'],
    schema: {
      value: 'test'
    },
    events: {
      click: function() {
        alert('Teste')
      }
    }
  })
})