Vue - Bind to innerHTML

by Ben Clayton

HTML

<div id="app" onchange="alert('change')">
  <hr>
  <div v-demo:foo.a.b="message"></div>
  <hr>
  <div v-myhtml="message"></div>


  <hr>
  <div v-twoway="message" contenteditable></div>
</div>

https://stackoverflow.com/questions/47200760/vuejs-directive-two-way-binding<br>
Try this in developer tools console ('result' window)<br>
vm.$data.message = "&lt;h1&gt;Hello Bert&lt;/h1&gt;"

CSS

#app {
  padding: 20px;
}

h1 {
  color: red;
  font-size: 24px;
}

Vue

Vue.directive('demo', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})

Vue.directive('myhtml', {
  bind: function (el, binding, vnode) {
    el.innerHTML =binding.value
  },
	update: function (el, binding, vnode) {
    el.innerHTML =binding.value
  }
})

Vue.directive('twoway', {
  bind: function (el, binding, vnode) {
    var select = $(el);
    console.log( select.html() , binding.value );
    select
      .html(binding.value)
      .trigger('change')
      .on('keyup', function () {
      	var ex = binding.expression;
        // if binding expression is a dotted path then resolve parts seperately
        var bits = ex.split('.');
        var path = vnode.context;
        var i=0;
        while (i < bits.length -1) {
        	path = path[bits[i++]];
        }
        if ( typeof path[bits[i]] != 'undefined' ) {
          path[bits[i]] = select.html();     
        }
				vnode.context.$emit('change');
        console.log( 'change' );
      })
    },
	update: function (el, binding, vnode) {
		
    if ( el.innerHTML != binding.value ){
    	// this damages the cursor position, a bit of a pain !!!!
    	el.innerHTML =binding.value
    }
  }
});


window['vm'] = new Vue({
  el: '#app',
  data: {
    message: '<h1>Hello World</h1>'
  }
})
console.log("VM inited",vm);