Vue - Directive to insert and execute html containing script tags
inset html containing script tags. And execute the scripts.
by Ben Clayton
HTML
<script src="https://unpkg.com/vue"></script>
<div id="app"></div>
<hr>
<script id="tmpl-app" type="text/x-template">
<div>
<h4>{{ global.title }}</h4>
<hr>
<div v-html="widgetcode"></div>
<hr>
<div v-dynamic="widgetcode"></div>
</div>
</script>
CSS
body {
font-size: 20px;
}
.text {
font-size: 24px;
}
.box {
border: 1px solid red;
}
JavaScript
//---------------------------------------------------------
Vue.directive('dynamic', {
bind: function(el, binding, vnode) {
var s = JSON.stringify
el.innerHTML = binding.value;
function insertAndExecute(domelement) {
var scripts = [];
debugger;
var ret = domelement.childNodes;
for (var i = 0; ret[i]; i++) {
if (scripts && nodeName(ret[i], "script") && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript")) {
scripts.push(ret[i].parentNode ? ret[i].parentNode.removeChild(ret[i]) : ret[i]);
}
if (ret[i]){
insertAndExecute(ret[i]);
}
}
for (script in scripts) {
evalScript(scripts[script]);
}
}
function nodeName(elem, name) {
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
}
function evalScript(elem) {
data = (elem.text || elem.textContent || elem.innerHTML || "");
var head = document.getElementsByTagName("head")[0] || document.documentElement,
script = document.createElement("script");
script.type = "text/javascript";
script.appendChild(document.createTextNode(data));
head.insertBefore(script, head.firstChild);
head.removeChild(script);
if (elem.parentNode) {
elem.parentNode.removeChild(elem);
}
}
insertAndExecute(el);
}
})
var vm = new Vue({ // create a root Vue instance
el: '#app', // this div gets replaced when View is rendered
template: '#tmpl-app',
data: function() {
return {
global: {
title: "Test Injected html with script tag execution"
}
}
},
created: function() {
// this.$data.global.name = 'BERTTY';
},
computed: {
widgetcode: function() {
return "hello from widget" + "<scr" + "ipt>alert('Hi 1')</scr" + "ipt><div><scr" + "ipt>alert('Hi 2')</scr" + "ipt></div>";
}
}
});