Messing with Vue.compile()
Abusing the internal compile API
by Thorsten
HTML
<div id="app">
<button @click="index = 0">First</button>
<button @click="index = 1">Second</button>
<button @click="index = 2">I work, no staticRenderFns here</button>
<dynamic v-bind:template="html[index]"></dynamic>
</div>
JavaScript
// Reference array sent to dynamic staticRenderFns
var staticRenderFns = [];
var dynamic = {
props: ['template'],
data() {
return {
templateRender: null,
};
},
render(h) {
if (!this.templateRender) {
return h('div', 'loading...');
} else { // 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() {
var 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 (var i in res.staticRenderFns) {
//staticRenderFns.push(res.staticRenderFns[i]);
this.$options.staticRenderFns.push(res.staticRenderFns[i])
}
}
}
},
};
new Vue({
el: "#app",
data: {
html: [
'<div><span>First template</span></div>',
'<div><span>Second template</span></div>',
'<div>Working template, no staticRenderFns here</div>'],
index: 0,
},
components: {
dynamic
},
});