SOURCE

console 命令行工具 X clear

                    
>
console
class Index {
  el = ''
  data = {}
  constructor({
    el,
    data
  }) {
    this.el = el
    this.data = new Proxy(data, {
      get(target, name) {
        return target[name]
      },
      set(obj, prop, value) {
        obj[prop] = value
        this.render()
        return true
      }
    })
  }
  template(tpl, data) {
    var data = data;
    var reg = [
        /{{([^}}]+)?}}/g,
        /(^( )?(if|for|switch))(.*)?/g,
        /(^( )?(else))(.*)?/g,
        /(^( )?(var|case|break|{|}))(.*)?/g,
        /(^( )?(end))(.*)?/g,
        /<\w*>\w*{{\w*}}\w*<\/\w*>/g
      ],
      match, code = 'var r=[];',
      cursor = 0;
    var add = function (line, js) {
      js ? code += line.match(reg[1]) ? line + '{\n' : line.match(reg[2]) ? '}' +
        line + '{' : line.match(reg[3]) ? line + '\n' : line.match(reg[4]) ? '}' : 'r.push(' + line + ');\n' :
        code += 'r.push("' + line.replace(/"/g, '\\"') + '");\n';
    };
    while (match = reg[0].exec(tpl)) {
      add(tpl.slice(cursor, match.index), false);
      add(match[1], true);
      cursor = match.index + match[0].length;
    }
    add(tpl.substr(cursor, tpl.length - cursor));
    code += 'return r.join("");';
    var scope = [];
    for (const key in data) {
      scope.push(key);
    }

    return new Function(`var {${scope.join(',')}} = arguments[0];` + code.replace(/[\r\t\n]/g, '')).call(this, data);
  }
  render() {
    let el = document.querySelector(this.el)
    el.innerHTML = template(el.innerHTML, data)
  }
}

new Index({
  el: '#app',
  data: {
    t1: 1
  }
})
<div id="app">
  {{t1}}
</div>