1- 模板

作者: 我爱阿桑 | 来源:发表于2020-07-13 17:17 被阅读0次
1 .拿到模板
  let tmpNode= document.querySelector('#root')
2.拿到数据
 let data = {
      name: '一个新name',
      message: '一个消息'
    };
3.将数据放入模板中

一般都是使用递归,在真正的 Vue 源码中是 DOM -> 字符串模板 -> VNode -> 真正的 DOM

// template   DOM元素
let rkuohao = /\{\{(.+?)\}\}/g
 function  complier( template ,data){
     let childNodes = template.childNodes
     for( let i = 0; i<childNodes.length; i++){
         let type = childNodes[ i ].nodeType; // 1 元素, 3 文本节点
        if(type==3){
         let txt = childNodes[i].nodeValue;
         txt = txt.replace(rkouhao,function( - ,g){  // replace 使用正则匹配一次 函数就会被调用一次                                                                    
                                                  // 函数的 第 0 个参数 表示匹配到的内容
                                                   // 函数的 第 n 个参数 表示正则中的 第 n 组

           let key=g.trim()  // 写在双花括号里面的 东西(相当于key)
           let value = data[key]
           return value
       })
          // 注意:  txt 现在和 DOM 元素是没有关系
          childNodes[ i ].nodeValue = txt;
    }else if ( type === 1 ) {
          // 元素, 考虑它有没有子元素, 是否需要将其子元素进行 判断是否要插值
          compiler( childNodes[ i ], data );
        }
 }
}
// 利用 模板生成一个 需要被渲染的 HTML 标签 ( 准 真正在页面中显示的 标签 )
    let generateNode = tmpNode.cloneNode( true ); // 注意这里是 DOM 元素, 可以这么用

 compiler( generateNode, data ); // 将{{}} 替换掉

4..将 渲染好的 HTML 加到页面中
    root.parentNode.replaceChild( generateNode, root );
5 全部代码
 <!--
 * @Author: MJC
 * @Date: 2020-07-13 16:24:09
 * @LastEditTime: 2020-07-13 16:36:44
--> 
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <!-- 写模板 -->
  <div id="root">
    <div>
      <p>{{name}}-{{message}}</p>
    </div>
    <p>{{name}}</p>
    <p>{{message}}</p>
  </div>

  <script>


    let rkuohao = /\{\{(.+?)\}\}/g;
    // 步骤拆解
    // 1. 拿到模板
    // 2. 拿到数据 ( data )
    // 3. 将数据与模板结合, 得到 的是 HTML 元素 ( DOM 元素 )
    // 4. 放到页面中

    // 1. 拿到模板
    let tmpNode = document.querySelector( '#root' ); // 元素拿到了 模板就是他了
    // 2  拿到数据 ( data )
    let data = {
      name: '一个新name'
      , message: '一个消息'
    };

    // 3. 将数据放到模板中( ??? )
    //  一般都是使用 递归
    // 在现在这个案例中 template 是 DOM 元素,
    // 在真正的 Vue 源码中是 DOM -> 字符串模板 -> VNode -> 真正的 DOM
    function compiler( template, data ) {
      let childNodes = template.childNodes; // 取出子元素
      for ( let i = 0; i < childNodes.length; i++ ) {
        let type = childNodes[ i ].nodeType; // 1 元素, 3 文本节点
        if ( type === 3 ) {
          // 文本节点, 可以判断里面是否有 {{}} 插值
          let txt = childNodes[ i ].nodeValue; // 该属性只有文本节点才有意义

          // 有没有双花括号??? 
          txt = txt.replace( rkuohao, function ( _, g ) { // replace 使用正则匹配一次 函数就会被调用一次
                                                    // 函数的 第 0 个参数 表示匹配到的内容
                                                    // 函数的 第 n 个参数 表示正则中的 第 n 组
            let key = g.trim(); // 写在双花括号里面的 东西
            let value = data[ key ];

            // 将 {{ xxxx }} 用这个 值替换
            return value;
          } );


          // 注意:  txt 现在和 DOM 元素是没有关系
          childNodes[ i ].nodeValue = txt;
        } 
        else if ( type === 1 ) {
          // 元素, 考虑它有没有子元素, 是否需要将其子元素进行 判断是否要插值
          compiler( childNodes[ i ], data );
        }
      }
    }

    // 利用 模板生成一个 需要被渲染的 HTML 标签 ( 准 真正在页面中显示的 标签 )
    let generateNode = tmpNode.cloneNode( true ); // 注意这里是 DOM 元素, 可以这么用

    console.log( tmpNode );
    compiler( generateNode, data ); // 将 坑 替换掉
    console.log( generateNode );

    // 我们此时是没有生成 新的 template, 所以这里看到的 是直接在页面中就更新的数据, 因为 DOM 是引用类型
    // 这样做 模板就没有了

    // 4. 将 渲染好的 HTML 加到页面中
    root.parentNode.replaceChild( generateNode, root );

    // 上面的思路有很大的问题:
    // 1. Vue 使用的 虚拟 DOM
    // 2. 只考虑了 单属性 ( {{ name }} ), 而 Vue 中大量的使用层级 ( {{ child.name.firstName }} )
    // 3. 代码没有整合
  </script>
</body>
</html>

相关文章

  • 1- 模板

    1 .拿到模板 2.拿到数据 3.将数据放入模板中 一般都是使用递归,在真正的 Vue 源码中是 DOM -> 字...

  • 【常用设计模式】观察者-模板-策略-责任链-适配器-代理-装饰器

    ==目录== 1-行为型-6个1-观察者模式2-模板模式3-策略模式4-责任链模式5-状态模式6-命令模式 2-结...

  • C++模板系列1-基础

    函数模板 如下面的函数模板参数: 其中,T1,T2,T3三个类型,只有出现在函数形参中的参数可以被编译器自动推导出...

  • 1-从写作模板开始学起

    对于写作来说,我们通常都是想到哪里写到哪里。 如果写作内容不公开的话,这种做法无可厚非。 但是,若我们需要公开写作...

  • 听课笔记,sam老舅讲课

    2020-07-05 组长的职责 行动的典范,在自己擅长的领域。 1-根据参考模板,写出要做的方向,也就是1.0模...

  • 代码分层

    一、分层结构 1-开放接口层 可以直接封装service方法暴露成RPC接口 2-终端显示层 各个端的模板渲染并执...

  • 领导力培训和发展行业的电子学习模板

    模板一: 模板二: 模板三: 模板四: 模板五: 模板六: 模板七: 模板八: 模板九: 模板十: 模板十一: 模...

  • vue模板实现1-简单正则替换

    对模板的很粗糙的实现,就是简单地用正则处理了一下,还加了一个报错。有很多不完善的地方,欢迎指出。

  • 有了这套画册模板设计之路不再迷茫!超赞!

    indesign模板介绍 时尚写真画册模板、婚礼画册模板、摄影写真画册模板、 人物展示画册模板、服装展示画册模板;...

  • 08_模板层补充

    模板层 一、模板层导入与继承 模板导入: 先码一个好看的模板 语法:{% include '模板名称' %} 模板...

网友评论

      本文标题:1- 模板

      本文链接:https://www.haomeiwen.com/subject/jeracktx.html