模版引擎
数组join法(字符串)
es6反引号法(模版字符串换行)
mustache (小胡子)
引入mustache
模版引擎的使用
mustache.render(templatestr,data)
mustache.render
循环简单数组
循环复杂数组
循环单项数组
数组的嵌套
mustache底层核心机制
使用正则实现简单的替换机制(注意点replace替换的时候第二个参数可以为一个函数函数的形参,第一个参数代表查询的第一个正则机制,第二个为找到data中的第二个参数)
但是mustache不能简单使用正则来表示,他中间的话牵扯到的数据类型比较复杂
mustache的原理
什么是tokens
循环状态下的tokens
手写mustache库
安装依赖运行node解析js文件
npm init
npm i -D webpack@4 webpack-dev-server@3 --legacy-peer-deps
新建webpack.congfig.js文件
const path = require('path') // 引用path模块module.exports = { // 这里是commrnt.js语法// 使用开发模式打包mode:"development",// 入口文件entry:"./src/index.js",// 打包后的出口文件output:{filename:'build.js',},devServer:{contentBase:path.join(__dirname,"www"),compress:false,port:8000,publicPath:'xuni'}
}
建立这样的文件格式
index.html文件代码如下
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title></title>
</head>
<body><script src="/xuni/build.js"></script><script>let temple= `我买了一个{{thing}},好{{good}}`let data={}console.log(window. window.vueMustache);window.vueMustache.render(temple,data)</script>
</body>
</html>
我们需要手写算法了!!!!
这个文件是扫描器函数
这个文件是我们需要获取到当前的文件格式
扫描器函数的目的就是为了获取模版,并把它进行拆分
具体的拆分如下
我们把这个模版分为scanUntil和scan2个过程,scanUntil是模拟的是"{{"之前的把它拆分出去,scan这个函数是相当于跳过”{{“,利用scasnUntil这个函数对他进行运用
判断代码逻辑如下
// 扫描器函数
export default class Scanaer{constructor(temple){console.log("我是",temple);//将子列写在自己身上this.temple=temple//设计一个指针this.pio=0;//尾巴,最开始尾巴是全文this.tail=temple}//相当于是跳过“{{”这个字符没有返回值scan(tag){if(this.tail.indexOf(tag)==0){this.pio+=tag.length;//尾巴也要进行变化为从当前指针开始到最后的所有字符this.tail=this.temple.substring(this.pio)}}// 让指针扫描,遇见指定内容返回,并返回结束前的返回值scanUtil(stopTop){//记录当前位置指针的当前位置let pio_backup=this.pio// 当尾巴不等于0的时候,或者当我的指针小于当前字符串的长度的时候,如果不小于当前的长度的话就会一直往后走,导致死循环while(this.eos()&&this.tail.indexOf(stopTop)!==0){this.pio++//让尾巴也跟着变化,获取到指针位置变化后的尾巴this.tail=this.temple.substring(this.pio)}//返回指针开始的值到现在的值的所有文字return this.temple.substring(pio_backup,this.pio)}//判断我的指针小于当前字符串的长度的时候,如果不小于当前的长度的话就会一直往后走,导致死循环 end 0f stringeos(){return this.pio<this.temple.length}
}
在index。js文件中的代码
import Scanaer from "./Scanner";
window.vueMustache={render(temple,data){//实例化一个扫描器,构造时提供参数,这个参数就是模版字符串//这个参数就是给模版字符串工作的let Scanaerl=new Scanaer(temple)// let a= Scanaerl.scanUtil("{{")// console.log(a,);// console.log(Scanaerl.pio,"测试扫描器函数是否能到指定内容返回");// Scanaerl.scan("{{")// console.log(Scanaerl.pio,"测试扫描器函数是否可以跳过指定内容");while(Scanaerl.pio!=temple.length){let a= Scanaerl.scanUtil("{{")console.log(a,"获取到的");Scanaerl.scan("{{")let b= Scanaerl.scanUtil("}}")console.log(b,"获取到的");Scanaerl.scan("}}")}}
}
生成tokens数组
创建这样的目录文件
import Scanaer from "./Scanner";
export default function createTokens(temple) {let tokens = [];let scanaer = new Scanaer(temple);let word;//让扫描器工作while (scanaer.eos()) {console.log("111");word = scanaer.scanUtil("{{")//运行到word到最后的时候会出现字符串的情况if (word !== '') {tokens.push(["text", word])}scanaer.scan("{{")word = scanaer.scanUtil("}}")//判断是否是#或者/的判断if (word !== "") {if (word[0] == "#") {tokens.push(["#", word.substring[1]])} else if (word[0] == "/") {tokens.push(["/", word.substring[1]])} else {tokens.push(["text", word])}}scanaer.scan("}}")}return tokens
}
index,js文件
import Scanaer from "./Scanner";
import createTokens from "./createTokens.js"
window.vueMustache={render(temple,data){let tokens=createTokens(temple)console.log(tokens);}}
但是以上的方法不能满足于二维数组的使用