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")