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

上文探究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>Documenttitle>
head>
<body>
    <script src = "/xuni/bundle.js">script>
    <script>
        GrManagData.render();
    script>
body>
html>

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

然后 html中 引入js 再调用GrManagData下的render
我们在浏览器中访问
控制台输出如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第1张图片
也是没有任何问题

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

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

探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第2张图片
这里 我们定义了模板字符串和data对象数据 然后传入我们的render
是不是和我们之前的mustache有点像啊 所以 其实很多时候难的只是一个开始
然后 我们在src下的 index.js中的GrManagData对象中将render改一下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第3张图片
这里 接一下这两个参数 然后 控制台输出一下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第4张图片
可以看到 我们输出的内容就在这里了

那么 我们要进行的就是 如何将模板字符串转成tokens
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第5张图片
那么 我们之前也看过 tokens是根据 花括号去分割的
那么 我们就得有个机制去寻找花括号的位置

这里 我们先打开mustache.js 开开源码是怎么写的
这里面有一个类 叫 Scanner
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第6张图片
顾名思义 扫描器
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第7张图片
它通过这个来实现一个扫描字符串的功能

我们在src下创建一个 Scanner.js
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第8张图片
编写代码如下

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作为参数

我们运行结果如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第9张图片
可以看到 我们的constructor中输出的内容就正常展示了

说明我们的类对象已经实例化成功了 但官方代码中还有两个函数 scan和scanUtil
我们也是声明一下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第10张图片
然后 我们来写一下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);
    }
}

运行结果如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第11张图片
最后 console.log(Scannerdom.pos); 输出了 6
那么 我们来看一下这个字符串
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第12张图片
字符串是从零开始的 第六个 正好是 {{ 符号开始的地方

好用是好用 但是 这个函数还没完成 我们要将这个函数寻找时路过的函数收藏起来
我们将 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);
    }
}

运行结果如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第13张图片
这里 我们 经过的内容就呈现出来了

然后呢 我们就需要看这个 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);
    }
}

运行结果如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第14张图片
输出的结果如下 就是 字符串的 {{ 自然是两个字符串 所以 它的长度是2 原本上次处理的pos是6 加上2 等于8 我们要在这个 8位置继续处理
所以 我们的逻辑就是 scanUtil和scan 反复调用 直到处理完为止

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

this.pos < this.templateStr.length

探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第15张图片
不然后面你就会发现它死循环了

然后 这个时候 我们将 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("{{");
        }
    }
}

运行结果如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第16张图片
可以看到 他将我们读取的内容都分开了
但现在只读了 {{
没有读 }}
这里我们还是要切开一下
这样写
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("}}");
        }
    }
}

运行结果如下
探究Vue源码:mustache模板引擎(6) 编写Scanner扫描类处理字符串按格式分割_第17张图片

你可能感兴趣的:(vue.js,前端,javascript)