VUE源码分析4 -- Mustache简介 和重写Scanner

2024-05-13 06:38

本文主要是介绍VUE源码分析4 -- Mustache简介 和重写Scanner,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

下面我们说Vue Dom实现,vue dom 兼容mustache项目。这个链接是mustache官方工程 mustache github地址

请看官方mustahce语法文档,变量前后添加两个大括号{{}},代表要侦测的数据。Vue官方也是兼容改特性。

下面我们要重零开始写Mustache,为什么要重零开始写mustache呢,因为我们追踪vue dom底层,mustache是跑不了的。

 

熟悉Mustache项目

首先我们先看看Mustache 案例,

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="https://unpkg.com/mustache@latest"></script>//引用mustache项目</head><body><div id="app"></div><div id="app1"></div></body><script type="text/javascript">console.log("here");var templateStr = `<ul>{{#arr}}<li>{{name}}的基本信息<div><p>姓名:{{name}}</p><p>性别:{{sex}}</p><p>年龄:{{age}}</p></div></li>{{/arr}}</ul>`;var data = {arr: [{"name": "小明","age": 12,"sex": "男"}, {"name": "小明","age": 12,"sex": "男"}, {"name": "小明","age": 12,"sex": "男"}]};var domStr = Mustache.render(templateStr, data);console.log(domStr);var container = document.getElementById('app');container.innerHTML=domStr;var templateStr1 = `		<ul>{{#arr}}<li>{{.}}</li>{{/arr}}</ul>`;var data1 ={arr:['A','B','C']}var domstr1 = Mustache.render(templateStr1, data1);console.log(domstr1);container.innerHTML +=domstr1;</script>
</html>

以上代码执行结果是

从上面给可以知道,{{name}},{{sex}},{{age}}是变量。并且{{#arr}}...{{/arr}}是否跟vue v-for相似。

 

Scanner类

下面分析mustache scanner类,为什么要先说scanner类呢,因为mustache把 模板字符串转成token,将tokens借和数据,解析为dom字符串。

例如,以下模板字符串是

<div><ol>{{#students}}<li>学生{{name}}的爱好是<ol>{{#hobbies}}<li>{{.}}</li>{{/hobbies}}</ol></li>{{/students}}</ol>
</div>

mustache内部先转成

[ ["text", "<div><ol>"],
["#", "students", [ ["text", "<li>学生"],
["name", "name"],
["text", "的爱好是<ol>"],
["#", "hobbies", [ ["text", "<li>"],
["name", "."],
["text", "</li>"],
]],
["text", "</ol></li>"],
]],
["text", "</ol></div>"] ]

为了验证以上步骤,我们修改官方mustache源码,把254代码改为

修改前:

修改后

然后网页输出信息为,可以看出此时模板字符串输出信息为tokens信息。

上面mustache源码在github链接下,请自行下载查看代码下载

 

下面我们开始重写Scanner类,

先创建Scanner.js文件,然后创建Scanner类,然后创建scan()和scanUtil()函数,scan函数是用于跳过某个字符,在mustache源码是跳过 {{ 和 }} 字符串。

export default class Scanner{constructor(templateStr){}scan(tag){//跳过 {{ 和 }}}scanUtil(stopTag){ //把字符串转成tokens}
}

scanUtil()函数功能用于把模板字符串转成tokens。

scan()是用于跳过某些字符串。

接下来我们继续写这两个函数代码,先看所有源码

Scanner.js

export default class Scanner{constructor(templateStr) {console.log(templateStr);this.templateStr = templateStr;//将模板字符串写道实例身上this.pos = 0;//当前位置this.tail = templateStr;}scan(tag){if(this.tail.indexOf(tag)==0){//第一位就是0this.pos += tag.length;this.tail = this.templateStr.substring(this.pos);}}scanUtil(stopTag){// console.log("scanUtil",stopTag);const pos_backup = this.pos;//当尾巴开头不是stopTag时候,说明没有扫描到到stopTag//写eos很必要,因为防止找不到,最后也要停止下来while(this.tail.indexOf(stopTag)!=0 && !this.eos()){this.pos++;//把尾巴改为当前扫描剩余字符串this.tail = this.templateStr.substring(this.pos);// console.log(this.tail);}return this.templateStr.substring(pos_backup,this.pos);}eos(){return this.pos >= this.templateStr.length;}
}

上面这个代码没什么好说的,都是基本截取字符串算法,自行手敲一次理解就行。

index.js

import Scanner from './Scanner.js'
//提供window全局方法
window.TemplateEngine = {render(templateStr,data){var scanner = new Scanner(templateStr);var word ;while(scanner.pos!=scanner.templateStr.length)// while(counter --){word = scanner.scanUtil("{{");console.log("word:",word);scanner.scan("{{");// console.log("word:",word);word = scanner.scanUtil("}}");console.log("word:",word);scanner.scan("}}");// console.log("word:",word);}}
}

在上面代码注意,在这里创建一个全局的对象TemplateEngine。然后一直循环截取字符串。

 

index.js

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title></title><script src="/xuni/bundle.js" type="text/javascript" charset="utf-8"></script></head><body>213123</body><script type="text/javascript">var Str = "<h1>我买了一个{{thing}},好{{mood}}</h1>;"var data = {}TemplateEngine.render(Str)</script>
</html>

上面代码是创建一个模板字符串Str,把Str放到TemplateEngine.render()函数转换成tokens,然后查看浏览器console输出。

以上是mustache scanner类源码,其实很简单,就是把模板字符串转为tokens一些算法。感兴趣的小伙伴可以自行尝试,重写Scanner类源码地址在这里下载 点我下载

这篇关于VUE源码分析4 -- Mustache简介 和重写Scanner的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/984958

相关文章

PostgreSQL简介及实战应用

《PostgreSQL简介及实战应用》PostgreSQL是一种功能强大的开源关系型数据库管理系统,以其稳定性、高性能、扩展性和复杂查询能力在众多项目中得到广泛应用,本文将从基础概念讲起,逐步深入到高... 目录前言1. PostgreSQL基础1.1 PostgreSQL简介1.2 基础语法1.3 数据库

Python库 Django 的简介、安装、用法入门教程

《Python库Django的简介、安装、用法入门教程》Django是Python最流行的Web框架之一,它帮助开发者快速、高效地构建功能强大的Web应用程序,接下来我们将从简介、安装到用法详解,... 目录一、Django 简介 二、Django 的安装教程 1. 创建虚拟环境2. 安装Django三、创

Spring Security重写AuthenticationManager实现账号密码登录或者手机号码登录

《SpringSecurity重写AuthenticationManager实现账号密码登录或者手机号码登录》本文主要介绍了SpringSecurity重写AuthenticationManage... 目录一、创建自定义认证提供者CustomAuthenticationProvider二、创建认证业务Us

Android 缓存日志Logcat导出与分析最佳实践

《Android缓存日志Logcat导出与分析最佳实践》本文全面介绍AndroidLogcat缓存日志的导出与分析方法,涵盖按进程、缓冲区类型及日志级别过滤,自动化工具使用,常见问题解决方案和最佳实... 目录android 缓存日志(Logcat)导出与分析全攻略为什么要导出缓存日志?按需过滤导出1. 按

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

MySQL中读写分离方案对比分析与选型建议

《MySQL中读写分离方案对比分析与选型建议》MySQL读写分离是提升数据库可用性和性能的常见手段,本文将围绕现实生产环境中常见的几种读写分离模式进行系统对比,希望对大家有所帮助... 目录一、问题背景介绍二、多种解决方案对比2.1 原生mysql主从复制2.2 Proxy层中间件:ProxySQL2.3

MySQL 索引简介及常见的索引类型有哪些

《MySQL索引简介及常见的索引类型有哪些》MySQL索引是加速数据检索的特殊结构,用于存储列值与位置信息,常见的索引类型包括:主键索引、唯一索引、普通索引、复合索引、全文索引和空间索引等,本文介绍... 目录什么是 mysql 的索引?常见的索引类型有哪些?总结性回答详细解释1. MySQL 索引的概念2

基于Python Playwright进行前端性能测试的脚本实现

《基于PythonPlaywright进行前端性能测试的脚本实现》在当今Web应用开发中,性能优化是提升用户体验的关键因素之一,本文将介绍如何使用Playwright构建一个自动化性能测试工具,希望... 目录引言工具概述整体架构核心实现解析1. 浏览器初始化2. 性能数据收集3. 资源分析4. 关键性能指

python使用Akshare与Streamlit实现股票估值分析教程(图文代码)

《python使用Akshare与Streamlit实现股票估值分析教程(图文代码)》入职测试中的一道题,要求:从Akshare下载某一个股票近十年的财务报表包括,资产负债表,利润表,现金流量表,保存... 目录一、前言二、核心知识点梳理1、Akshare数据获取2、Pandas数据处理3、Matplotl

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group