JSFiddle - React, Tailwind, and code Playground
by lid0
HTML
<script src="https://unpkg.com/[email protected]/dist/vue.global.js"></script>
<template id="_app">
<my-comp></my-comp>
<button @click="'$event.currentTarget.innerHTML+=\'Boom\''.run(this, $event)" >
Run
</button>
</template>
<html>
<div id="app">
</div>
</html>
JavaScript
/*
@author: lidlanca 2021 march 13
VUE compiler, will try its best to prefix a context to identifiers
<b @click"doStuff()">
will be rendered as: _ctx.doStuff()
<b @click"age=22">
will be rendered as: _ctx.age=22
so if we try
<b @click="alert('hello?')">
renders to:
onClick: $event => (_ctx.alert('hello?'))
This is a proof of concept of bypassing this limitation, but using
a string, and a helper method that will be added to the String prototype.
we will pass the following to the @click handler
'alert(\hello\')'.run(this)
like this:
<button @click="'alert(\hello\')'.run(this)">click</button>
and that will render to:
onClick: $event => ('alert(\hello\')'.run(this))
we pass "this" to .run(), this will actually be the component
the 2nd argument .run() accept is $event, which if we pass, the code we execute will then have access to it.
*/
// run will evaluate the content of the string, with the context that is passed in the first argument.
// we call also delegate the $event
String.prototype.run = function(_this,$event){
var code = this;
;(function(){
eval(code.toString()) // cast code to string
}.bind(_this))() // bind eval execution context to the injected _this
}
var myComp = Vue.defineComponent({
name:"myComp",
data(){
return {
"message": "hello you"
}
},
template: `<p><button @click="'this.message=\\'message changed via \\' + $event.type;alert(this.message);console.log($event)'.run(this,$event)">change message</button>Message: <b>{{ message }}</b></p>`
})
Vue.createApp({
template: document.getElementById("_app").innerHTML ,
components: {
myComp
}
}).mount("#app")