javascriptvue.jsmarkup

Convert HTML to a Vue component in runtime


I'm in process of learning Vue and i was building a simple wiki page. Raw article data are JSON file written in a custom markup. For instance, the following markup: The ''sun'' is {r=black black} should be "compiled" in this way: <p>The <b>sun</b> is <Ref path="/black">black</p> I'm able to do this with regexp and string manipulation, but i can't use that string as template option since it works with only static inputs. If it was only html i could've used v-html directive or something else related. My template fetch the JSON file and parse my custom markup according to the criteria i've choosen. What it gets out of it, is a string (Vue markup) can't be assigned to 'template' options since it accept only static string and doesn't recognize any variable.

I tried assigning the template options a vue markup compiled or using a runtime-compiler. Maybe i'm wrong. How could i do?


Solution

  • You can compile a vue template with compile() and insert into your current template with <Component>. Also we need to change alias 'vue' import to 'vue/dist/vue.esm-bundler.js' in vite.config.js to enable this feature.

    enter image description here

    Changed files from npm create vue@latest:

    App.vue

    <script setup>
    
    import { ref, compile } from 'vue';
    
    const msg = ref('Hello world!');
    const component = ref(compile('<HelloWorld :msg="msg"></HelloWorld>'));
    
    </script>
    
    <template>
        <main>
            <Component :is="component" :msg="msg"></Component>
        </main>
    </template>
    

    main.js

    import './assets/main.css'
    
    import { createApp } from 'vue'
    import App from './App.vue'
    
    
    const app = createApp(App);
    import HelloWorld from './components/HelloWorld.vue'
    app.component('HelloWorld', HelloWorld);
    app.mount('#app')
    

    vite.config.js

    import { fileURLToPath, URL } from 'node:url'
    
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    
    // https://vitejs.dev/config/
    export default defineConfig({
        plugins: [
            vue(),
        ],
        resolve: {
            alias: {
                '@': fileURLToPath(new URL('./src', import.meta.url)),
                vue: 'vue/dist/vue.esm-bundler.js',
            }
        }
    })