探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割

news/2025/1/18 3:25:37/

上文探究Vue源码:mustache模板引擎(5) 对比rollup与webpack,在本地搭建webpack环境中 我们搭建了一个基本的webpack开发环境
那么 本文开始 我们就要写这方面的开发代码了
我们在 src下的index.js
代码如下

window.GrManagData = {render() {console.log(111);}
}

然后 www下的 index.html 编写代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script src = "/xuni/bundle.js"></script><script>GrManagData.render();</script>
</body>
</html>

我们js中 在 window对象上挂一个GrManagData对象
然后 里面写一个render函数

然后 html中 引入js 再调用GrManagData下的render
我们在浏览器中访问
控制台输出如下
在这里插入图片描述
也是没有任何问题

然后 我们将 www 下的 index.html中 script 部分改成这样

let templateStr = "你家好,我是{{ name }},我今年{{ age }}岁啦";
let data = {name: "小猫猫",age: 2
}
GrManagData.render(templateStr,data);

在这里插入图片描述
这里 我们定义了模板字符串和data对象数据 然后传入我们的render
是不是和我们之前的mustache有点像啊 所以 其实很多时候难的只是一个开始
然后 我们在src下的 index.js中的GrManagData对象中将render改一下
在这里插入图片描述
这里 接一下这两个参数 然后 控制台输出一下
在这里插入图片描述
可以看到 我们输出的内容就在这里了

那么 我们要进行的就是 如何将模板字符串转成tokens
在这里插入图片描述
那么 我们之前也看过 tokens是根据 花括号去分割的
那么 我们就得有个机制去寻找花括号的位置

这里 我们先打开mustache.js 开开源码是怎么写的
这里面有一个类 叫 Scanner
在这里插入图片描述
顾名思义 扫描器
在这里插入图片描述
它通过这个来实现一个扫描字符串的功能

我们在src下创建一个 Scanner.js
在这里插入图片描述
编写代码如下

export default class Scanner{constructor(templateStr) {console.log("这是 Scanner 类",templateStr);}
}

这里 我们还是定义了一个类对象

然后 我们改写 src下的index.js代码如下

import Scanner from "./Scanner";
window.GrManagData = {render(templateStr,data) {console.log(templateStr,data);//实例化一个Scanner类对象let Scannerdom = new Scanner(templateStr);}
}

我们先利用ES6的方法 import方式导入了Scanner
然后 通过new Scanner实例化了这个类
将templateStr作为参数

我们运行结果如下
在这里插入图片描述
可以看到 我们的constructor中输出的内容就正常展示了

说明我们的类对象已经实例化成功了 但官方代码中还有两个函数 scan和scanUtil
我们也是声明一下
在这里插入图片描述
然后 我们来写一下scanUtil
这个函数的作用在于 拿到指定符号的下标

编写 Scanner 代码如下

export default class Scanner{constructor(templateStr) {this.templateStr = templateStr;this.pos = 0;this.tail = templateStr;}//路过指定内容  没有返回值scan() {}//通过指针进行扫描 直到拆解 并返回扫描过程中的字符串scanUtil(endIndex) {while (this.tail.indexOf(endIndex) != 0) {this.pos++;this.tail = this.templateStr.substr(this.pos);}}
}

我们这里判断 如果 tail 中包含有指定的符号 就继续往下循环
while 循环只要条件成立 就会一直执行
然后 将pos加1
然后 通过 substr 从this.templateStr中取出对应下标的字符串
例如 第一次 是 pos 0 加一之后 去掉的就是 家好,我是{{ name }},我今年{{ age }}岁啦
然后 第二次 又pos加1 取到 好,我是{{ name }},我今年{{ age }}岁啦
一直向下转移

然后 我们在index.js中调用看看效果
index.js编写代码如下

import Scanner from "./Scanner";
window.GrManagData = {render(templateStr,data) {console.log(templateStr,data);//实例化一个Scanner类对象let Scannerdom = new Scanner(templateStr);Scannerdom.scanUtil("{{");console.log(Scannerdom.pos);}
}

运行结果如下
在这里插入图片描述
最后 console.log(Scannerdom.pos); 输出了 6
那么 我们来看一下这个字符串
在这里插入图片描述
字符串是从零开始的 第六个 正好是 {{ 符号开始的地方

好用是好用 但是 这个函数还没完成 我们要将这个函数寻找时路过的函数收藏起来
我们将 scanUtil 函数改成这样

//通过指针进行扫描 直到拆解 并返回扫描过程中的字符串
scanUtil(endIndex) {const PosBackups = this.pos;while (this.tail.indexOf(endIndex) != 0) {this.pos++;this.tail = this.templateStr.substr(this.pos);}return this.templateStr.substring(PosBackups,this.pos);
}

这里 我们定义了一个常量 PosBackups 用来存住字符串开始的位置
然后 最后返回 调用 substring 获取指定的内容 指定的就是 从PosBackups到this.pos下标中间的内容
然后 我们尝试调用并输出一下返回值
index.js代码修改如下

import Scanner from "./Scanner";
window.GrManagData = {render(templateStr,data) {console.log(templateStr,data);//实例化一个Scanner类对象let Scannerdom = new Scanner(templateStr);const str = Scannerdom.scanUtil("{{");console.log(str);}
}

运行结果如下
在这里插入图片描述
这里 我们 经过的内容就呈现出来了

然后呢 我们就需要看这个 scan 函数 这个函数其实功能比较弱
我们将 Scanner 中的scan代码编写如下

//路过指定内容  没有返回值
scan(tog) {if(this.tail.indexOf(tog) == 0) {this.pos += tog.length;this.tail = this.templateStr.substring(this.pos);}
}

判断 如果tail中没有包含指定符号了 然后就让pos加上特殊符号的长度
我们在index.js中这样写

import Scanner from "./Scanner";
window.GrManagData = {render(templateStr,data) {console.log(templateStr,data);//实例化一个Scanner类对象let Scannerdom = new Scanner(templateStr);const str = Scannerdom.scanUtil("{{");Scannerdom.scan("{{");console.log(Scannerdom.pos);}
}

运行结果如下
在这里插入图片描述
输出的结果如下 就是 字符串的 {{ 自然是两个字符串 所以 它的长度是2 原本上次处理的pos是6 加上2 等于8 我们要在这个 8位置继续处理
所以 我们的逻辑就是 scanUtil和scan 反复调用 直到处理完为止

但首先 要将 scanUtil 的循环条件改一下
加一个

this.pos < this.templateStr.length

在这里插入图片描述
不然后面你就会发现它死循环了

然后 这个时候 我们将 src下的 index.js代码改成这样

import Scanner from "./Scanner";
window.GrManagData = {render(templateStr,data) {console.log(templateStr,data);//实例化一个Scanner类对象let Scannerdom = new Scanner(templateStr);while(Scannerdom.pos != templateStr.length) {let sTr = Scannerdom.scanUtil("{{");console.log(sTr);Scannerdom.scan("{{");}}
}

运行结果如下
在这里插入图片描述
可以看到 他将我们读取的内容都分开了
但现在只读了 {{
没有读 }}
这里我们还是要切开一下
这样写
index.js

import Scanner from "./Scanner";
window.GrManagData = {render(templateStr,data) {console.log(templateStr,data);//实例化一个Scanner类对象let Scannerdom = new Scanner(templateStr);let sTr;while(Scannerdom.pos != templateStr.length) {sTr = Scannerdom.scanUtil("{{");console.log("文本",sTr);Scannerdom.scan("{{");sTr = Scannerdom.scanUtil("}}");console.log("变量",sTr);Scannerdom.scan("}}");}}
}

运行结果如下
在这里插入图片描述


http://www.ppmy.cn/news/911616.html

相关文章

java设置打印字体大小_PHP调整字体大小打印到网络热敏打印机

我有以下代码&#xff0c;它像一个从PHP打印到我的爱普生热敏打印机的魅力 . 我们用它在办公室结账时在办公室打印客户订单 . 我想改变字体大小&#xff0c;使它看起来像一个更真实的食谱 . 以下是我使用的代码示例&#xff1a; $texttoprint "RECIPT TEXT \n NEXT LINE …

【Java反射机制详解】—— 每天一点小知识

&#x1f4a7; J a v a 反射机制详解 \color{#FF1493}{Java反射机制详解} Java反射机制详解&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页——微风撞见云的博客&#x1f390; &#x1f433; 《数据结构与算法》专栏的文章…

SQLRecon!MS-SQL渗透工具包

工具介绍 SQLRecon是一款使用C#开发的MS-SQL渗透工具包&#xff0c;专为攻击性侦察和后期渗透而设计&#xff1b;有关每种技术的详细使用示例可参阅 wiki 。 关注【Hack分享吧】公众号&#xff0c;回复关键字【230601】获取下载链接 类似工具还有&#xff1a;SharpSQLTools、P…

2.13 系统管理

文章目录 2.13 系统管理系统管理的概念系统管理员系统日志系统备份与恢复安全管理性能监控与优化更新和升级管理总结 2.13 系统管理 系统管理的概念 系统管理是指对计算机系统进行管理和维护的活动&#xff0c;包括硬件设备、操作系统、软件应用和网络等方面的管理。系统管理…

WAVE音频文件格式及其64位扩展格式的简要介绍

正文 关于 WAVE 文件格式&#xff0c;网上有不少介绍&#xff0c;但关于WAVE 64位扩展格式的介绍却是几乎没有。 所以本文的目的是简要介绍标准的 WAVE 格式&#xff0c;以及两种主要的扩展格式。 文中所有代码都用C语言来描述&#xff0c;尽管C语言有些不那么方便&#xff…

M60许可的下载说明

之前10月份的时候写过一个M60的基本搭建手册&#xff0c;圈子内很多朋友开始都在测试或者上线M60&#xff0c;我个人觉得如果你看过我之前写的M60搭建手册&#xff0c;再去看看官方的PPT和文档&#xff0c;测试或是上线应该问题不大。 前几天遇到一个朋友测试M60的时候LIC下载的…

【MySQL】DML数据处理之增删改

闲话 前段时间在准备考华子的od&#xff0c;然后也小小的偷了一下懒&#xff0c;估计是过不去了&#xff0c;还是老老实实回来更新博客吧&#xff0c;继续学习~ 一、添加数据 1、准备工作 首先我们创建一张表 t_decade_book_new DROP TABLE IF EXISTS t_decade_book_new; …

g726转pcm

g726转pcm 1077协议&#xff0c;别人的设备&#xff0c;没参数&#xff0c;获取音频包&#xff0c;解析得知是g726编码 刚开始找的是adpcm解码的&#xff0c;下面这个链接的https://blog.csdn.net/forfuture3513/article/details/51764814 测试发现都是电流兹兹声&#xff0c;…