How to write Vue syntax in v-html

WARNING: v-html may cause XSS. Make sure v-html is from reliable source. NEVER render v-html's contents by client input!

I recently got a task: Render a Vue program by special syntax that's provided by server side. For example, if the server provides: {link target="question1"}, I should let this syntax became something like this: <a v-on:click='target("question1")'></a>.

I changed this syntax successfully, but, how to trigger the event? When finding the help, I find a question from Stack Overflow that's talking about how to use Vue components in v-html.

The answer provides a workaround: use Vue.compile() to compile the given codes, then clear some caches, and fill it to some internal rendering variables. Finally, Vue.render() all of it.

Finally, how to trigger it? Easy, just add an event in methods instance. Looks like something like this:

// The whole reference:
// https://stackoverflow.com/a/45494778/7162445
import Vue from "vue";

export default {
    props: {
        template: {
            type: String,
            default() {
                return "";
            }
        }
    },
    data() {
        return {
            templateRender: null,
            staticRenderFns: [],
        };
    },
    render( h ) {
        if ( !this.templateRender ) {
            return h( "div", "加載中..." );
        }
        // If there is a template, I'll show it
        return this.templateRender();
    },
    watch: {
        // Every time the template prop changes, I recompile it to update the DOM
        template: {
            immediate: true,
            // makes the watcher fire on first render, too.
            handler() {
                let res = Vue.compile( this.template );
                this.templateRender = res.render;
                // staticRenderFns belong into $options,
                // appearantly
                this.$options.staticRenderFns = [];
                // clean the cache of static elements
                // this is a cache with the results from the staticRenderFns
                this._staticTrees = [];
                // Fill it with the new staticRenderFns
                for ( let i in res.staticRenderFns ) {
                    //staticRenderFns.push(res.staticRenderFns[i]);
                    this.$options.staticRenderFns.push( res.staticRenderFns[i]);
                }
            }
        }
    },
    methods: {
        target(input) {
            // Do whatever events
        }
    },
};