Vue

by lyquix

HTML

<div id="app">
  <div>
    <label for="string">String</label><br>
    <input id="string" name="string" v-model="string">
  </div>
  <div>
    <label for="hex">UTF8 to Hex</label><br>
    <input id="hex" name="hex" v-model="hex" readonly>
  </div>
  <div>
    <label for="utf8">Hex to UTF8</label><br>
    <input id="utf8" name="utf8" v-model="utf8" readonly>
  </div>
</div>

CSS

body, * {
  font-family: sans-serif;
  box-sizing: boder-box;
  margin: 0;
}

div {
  margin: 1em 0;
}

#app {
  margin: 1em;
  max-width: 960px;
}

input {
  width: 100%;
  border-radius: 3px;
  border: 1px solid #999;
  padding: 5px 3px;
  font-family: monospace;
}

Vue

new Vue({
  el: "#app",
  data: {
  	string: '',
    hex: '',
    utf8: ''
  },
  methods: {
    utf8_hex: function(str) {
      return Array.from(str).map(c => 
        c.charCodeAt(0) < 128 ? c.charCodeAt(0).toString(16).padStart(2, '0') :
        encodeURIComponent(c).replace(/\%/g,'').toLowerCase()
      ).join('');
    },
    hex_utf8: function(hex) {
      return decodeURIComponent('%' + hex.match(/.{1,2}/g).join('%'));
    }
  },
  watch: {
  	string: function() {
    	this.hex = this.utf8_hex(this.string);
      this.utf8 = this.hex_utf8(this.hex);
    },
  },
  mounted: function(){
  	this.string = 'Huöut væ 😂💥💖 Iñtërnâtiônàlizætiøn $¢€한𐍈';
  }
});