vue中的模板编译 {{}}

1、util.js


// 正则,?:匹配不捕获  不捕获当前的分组
// + 至少一个
// ?尽可能少匹配
// 源码里的模板编译  也是基于正则的

const defaultRE = /\{\{((?:.|\r?\n))+?\}\}/g;
export const util = {
  getValue(vm,expr){   //school.name
    let keys=expr.split('.');
    return keys.reduce((memo,current)=>{   //reduce具备迭代的功能
        memo=memo[current];   //memo =vm.school
        return memo;
    },vm)
  },
  compilerText(node, vm) {
    //编译文本  替换{{}}
    node.textContent = node.textContent.replace(
      defaultRE,
      function (...args) {
        return util.getValue(vm,args[1]);
      }
    );
  },
};

export function compiler(node, vm) {
  //node就是文档碎片
  let childNodes = node.childNodes;    // 只有一层  只有儿子  没有孙子

  // 将类数组转化成数组
  [...childNodes].forEach((child) => {
    //一种是元素,一种是文本
    if (child.nodeType == 1) {
      //1 元素   3表示文本
      compiler(child,vm);   //编译当前元素的孩子节点
    } else if (child.nodeType == 3) {
      util.compilerText(child, vm);
    }
  });
}

2、index.js

import { initState } from "./observe";
import Watcher from "./observe/watcher";
import { compiler,util } from "./util";
function Vue(options) {
  //vue中原始用户传入的数据
  this._init(options); // 初始化vue并且将用户选项传入
}

Vue.prototype._init = function (options) {
  //vue中初始化, this.$options  表示的是vue中参数

  let vm = this;
  vm.$options = options;

  // MVVM原理  需要数据重新初始化
  // 拦截数组的方法 和对象的属性
  initState(vm); // data  computed  watch

  // 初始化工作

  if (vm.$options.el) {
    vm.$mount();
  }
};

function query(el) {
  if (typeof el === "string") {
    return document.querySelector(el);
  }
  return el;
}


Vue.prototype._update = function () {
  // 用户传入的数据  去更新视图
  let vm = this;
  let el = vm.$el;

  // 要循环这个元素   将里面的内容  换成我们的数据

  // 需要匹配{{}} 的方式来进行替换
  let node = document.createDocumentFragment();
  let firstChild;
  while ((firstChild = el.firstChild)) {
    //每次拿到第一个元素  就将这个元素放入到文档碎片中。
    node.appendChild(firstChild); //appendChild 是具有移动功能的。
  }
  compiler(node, vm);
  el.appendChild(node);


  // 需要匹配{{}} 的方式来进行替换
  // 依赖收集  属性变化了   需要重新渲染 watcher和deep
};

// 渲染页面  将组建进行挂载
Vue.prototype.$mount = function () {
  let vm = this;
  let el = vm.$options.el; //获取元素
  el = vm.$el = query(el); //获取当前挂载的节点    vm.$el就是我要挂载的一个元素

  // 渲染是通过watcher来渲染的。
  // 渲染watcher 用于渲染的watcher
  // Vue 2.0 组建级别的更新   new Vue 产生的一个组件

  let updateComponent = () => {
    //更新组件,渲染组件
    console.log("执行");
    vm._update(); //更新组件
  };

  new Watcher(vm, updateComponent); //渲染watcher,默认会调用updateComponent 这个方法
};

export default Vue;

3、reduce具有迭代的功能

[1,2,3].reduce((memo,current)=>{
    memo+=current;
    return memo;
},0);


// 累加器

 4、正则 (匹配{{}})

const defaultRE = /\{\{((?:.|\r?\n))+?\}\}/g;

 

// 正则,?:匹配不捕获  不捕获当前的分组

// + 至少一个

// ?尽可能少匹配

// 源码里的模板编译  也是基于正则的

'{{}}'.match(/\{\{((?:.|\r?\n))+?\}\}/g);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

vues

刚好遇见你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值