Vue源码分析-模板解析

模板解析

模板解析流程:

  1. 将el的所有节点取出,放在文档碎片fragment对象中
  2. 将fragment对象的所有子节点进行递归解析处理
  3.  

插值语法解析

    1. 对插值语法(表达式)进行解析(与v-text指令解析一致),使用compileText方法
      1. 根据正则对象获取匹配到的表达式字符串
      2. 从vm实例上找到表达式对应的值
      3. 将属性值设置为文本节点的textContent

指令解析

    1. 一般指令解析
      1. 从标签节点中获取到指令名和表达式
      2. 从vm实例上拿到表达式的对应的值
      3. 根据指令操作标签节点的属性

v-text----textContent属性

v-html----innerHtml属性

v-class----className属性

v-model----value属性

      1. 将表达式的值设置到对应的属性上
      2. 指令解析后,移除元素此属性
    1. 事件指令解析
      1. 从标签节点找到获取到对应的事件名和表达式
      2. 根据表达式从vm实例methods中获取到函数
      3. 给当前元素节点绑定指定的事件名和回调函数
      4. 指令解析后,移除元素此属性
  1. 将解析后的文档对象fragment添加到el中显示

相关代码

mvvm.js

//编译模板

this.$compile = new Compile(options.el || document.body, this);

 

compile.js

function Compile(el, vm) {

  // 保存vm

  this.$vm = vm;  //为了能在其他函数内部获取到vm实例身上的数据

  // 获取dom元素保存起来

  this.$el = this.isElementNode(el) ? el : document.querySelector(el);

 

  if (this.$el) {

    // 1. 将元素所有子节点添加到新的创建文档碎片节点中

    this.$fragment = this.node2Fragment(this.$el);

    // 2. 递归编译文档碎片节点所有子节点

    this.init();

    // 3. 将编译好文档碎片节点添加到页面中生效

    this.$el.appendChild(this.$fragment);

  }

}

node2Fragment—得到文档随便对象

  node2Fragment: function (el) {

    // 创建文档碎片节点

    var fragment = document.createDocumentFragment(),

      child;

    // 将原生节点拷贝到fragment

    while ((child = el.firstChild)) {

      fragment.appendChild(child);

    }

    return fragment;

  },

Init—开始编译

  init: function () {

    // 递归编译所有子节点方法

    this.compileElement(this.$fragment);

  },

compileElement—接收文档碎片进行编译

  compileElement: function (el) {

    // 取出当前元素所有子节点

    var childNodes = el.childNodes,

      me = this;

    // 转换成数组进行遍历<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值