Search code examples
vue.jsdynamiccomponents

How to render Vue component which is coming from an html field of my database?


Let admit, I have in my database a field "content" where I store a component and it's data to be show. How can I render this component?

I know v-html to render the html but it didn't understand the component.

// My data coming from database:
// data.content = "<w-image slug="my-image-slug"></w-image>"

<template>
   <div v-html="data.content"></div> <!-- just show the html output -->
</template>
<script>
import WImage from '@/Components/Widgets/Image.vue'
...
export default {
   props:{
        data : Object,
        ...
    },
    components: {
        WImage,
        ...
    },
}
</script>

I guess it's not possible because it didn't compile the code. But, I'm generally surprise of what's possible to do so...
I give it a chance.


Solution

  • Based on the info you provided I could imagine a solution, like this:

    Vue.component("WImage", {
      props: ['slug'],
      template: `
        <div>{{ slug }}</div>
      `
    })
    
    new Vue({
      el: "#app",
      data() {
        return {
          htmlstring: "<w-image slug='my-image-slug'></w-image>"
        }
      },
      render(h) {
        return h({
          template: `<div>${ this.htmlstring }</div>`
        })
      }
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app"></div>

    If you know the possible components beforehand, then you could register/dynamically import them to a component that handles all of the HTML strings. Use the render function to render the HTML strings by passing it a component object, with template.

    You need the full build of Vue to do this trick - the normal build won't compile templates on the fly, so it won't work.