JSFiddle - React, Tailwind, and code Playground

by ruirui

HTML

Vue 动态数据绑定(四)2
<div id="app">
    <p>姓名:<span>{{user.name}}</span></p>
    <p>年龄:<span>{{user.age}}</span></p>
</div>

JavaScript

function Vue(obj) {
  this.el = obj.el;
  this.data = obj.data;
  new Compile(this.el, this);
}
function Compile(el, vm) {
  this.el = el;
  this.vm = vm;
  this.fragement = this.nodeToFragment(document.querySelector(this.el));
  this.compile(this.fragement);
  document.querySelector(this.el).appendChild(this.fragement);
}
Compile.prototype.nodeToFragment = function(el) {
  var fragment = document.createDocumentFragment();
  var child = el.firstChild;
  while (child) {
    fragment.appendChild(child); // 将Dom元素移入fragment中 注意: append的时候 原来的dom会删掉挂载在文档碎片上
    child = el.firstChild;
  }
  return fragment;
}
Compile.prototype.compile = function (el) {
  // 递归遍历所有的dom子元素 找到 {{}} 进行替换

  var childNodes = el.childNodes;
  console.log('------接下来是children--------')
  console.log(childNodes);
  childNodes.forEach((item) => {
    
    if(item.nodeType === 1) { // 元素节点
      this.compile(item);
    } else if (item.nodeType === 3) { // 文本内容
      console.log(item.nodeValue);
      var value = item.nodeValue.trim();
      var reg = /{{(.*?)}}/;
      if (value && reg.test(value)) {
        this.compileText(item, reg.exec(value)[1]);
      }
    }
  })
}
Compile.prototype.compileText = function(node, exp) {
	var newVal = this.parse(exp.trim())(this.vm.data);
  node.textContent = typeof newVal == 'undefined' ? '' : newVal;
}
Compile.prototype.parse = function (exp) {
  if (/[^\w.$]/.test(exp)) return; 
  
    var exps = exp.split('.');
    return function(obj) {
      for (var i = 0, len = exps.length; i < len; i++) {
          if (!obj) return;
          obj = obj[exps[i]];
      }
      return obj;
    }
}

let app = new Vue({
  el: '#app',
  data: {
    user: {
      name: 'sunrui',
      age: 25
    }
  }
})