端模板是什么?前端模板该如何实现?很多朋友可能对这个不太了解,那么,下面这篇文章将给大家介绍一下关于前端模板的原理以及简单的实现代码。
前端模板的发展
模板可以说是前端开发最常接触的工具之一。将页面固定不变的内容抽出成模板,服务端返回的动态数据装填到模板中预留的坑位,最后组装成完整的页面html字符串交给浏览器去解析。
模板可以大大提升开发效率,如果没有模板开发人员怕是要手动拼写字符串。
var tpl = ‘<p>’ + user.name + ‘</p>’;
$(‘body’).append(tpl);
在近些年前端发展过程中,模板也跟着变化:
现在以mustache模板为例,手动实现一个实现基本功能的模板。
模板字符串模板:index.txt
<!DOCTYPE html>
<html>
<head>
<meta charset=”utf-8″ />
<meta http-equiv=”X-UA-Compatible” content=”IE=edge”>
<title>Page Title</title>
<meta name=”viewport” content=”width=device-width, initial-scale=1″>
<link rel=”stylesheet” type=”text/css” media=”screen” href=”main.css” />
<script src=”main.js”></script>
</head>
<body>
<h1>Panda模板编译</h1>
<h2>普通变量输出</h2>
<p>username: {{common.username}}</p>
<p>escape:{{common.escape}}</p>
<h2>不转义输出</h2>
<p>unescape:{{&common.escape}}</p>
<h2>列表输出:</h2>
<ul>
{{#each list}}
<li class=”{{value}}”>{{key}}</li>
{{/each}}
</ul>
<h2>条件输出:</h2>
{{#if shouldEscape}}
<p>escape{{common.escape}}</p>
{{else}}
<p>unescape:{{&common.escape}}</p>
{{/if}}
</body>
</html>
模板对应数据:
module.exports = {
common: {
username: ‘Aus’,
escape: ‘<p>Aus</p>’
},
shouldEscape: false,
list: [
{key: ‘a’, value: 1},
{key: ‘b’, value: 2},
{key: ‘c’, value: 3},
{key: ‘d’, value: 4}
]
};
模板的使用方法:
var fs = require(“fs”);
var tpl = fs.readFileSync(‘./index.txt’, ‘utf8’);
var state = require(‘./test’);
var Panda = require(‘./panda’);
Panda.render(tpl, state)
这里开始讲模板语法token和普通字符串token开始统一编译生成字符串,并拼接成完整的字符串。
// 根据tokens和context混合拼接字符串输出结果
Panda.prototype.renderTokens = function (tokens, context) {
var result = ”;
var token, symbol, value;
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
value = undefined;
token = tokens[i];
symbol = token.type;
if (symbol === ‘#’) value = this.renderSection(token, context);
else if (symbol === ‘&’) value = this.unescapedValue(token, context);
else if (symbol === ‘=’) value = this.escapedValue(token, context);
else if (symbol === ‘text’) value = this.rawValue(token);
if (value !== undefined) result += value;
}
return result;
}
5. 绘制页面
页面字符串已经解析完成,可以直接输出:
Panda.prototype.render = function (tpl, state) {
if (typeof tpl !== ‘string’) {
return new Error(‘请输入字符串!’);
}
// 解析字符串
var tokens = this.cache[tpl] ? tokens : this.parse(tpl);
// 解析数据结构
var context = state instanceof Context ? state : new Context(state);
// 渲染模板
return this.renderTokens(tokens, context);
};
输出页面字符串被浏览器解析,就出现了页面。
以上只是简单的模板实现,并没有经过系统测试,仅供学习使用,源码传送门。成熟的模板引擎是有完整的异常处理,变量查找解析,作用域替换,优化渲染,断点调试等功能的。
总结
前端模板这块能做的东西还很多,很多框架都是集成模板的功能,配合css,js等混合编译生成解析好样式和绑定成功事件的dom。
另外实现模板的方式也有很多,本文的实现方式参考了mustache源码,模板标签内的代码被解析,但是是通过代码片段分类,变量查找的方式来执行的,将纯字符串的代码变成了被解释器执行的代码。
另外向vue这种可以实现双向绑定的模板可以抽空多看一看。