ijktpl v0.0.9
IJKTPL.JS
轻量,高效,极简与安全的模板库
你是不是对高效有什么误解?看来你还是不懂得内存的可贵
小DEMO
名字由来
IJK?(多意)项目里主多次使用i, j, k三个变量来进行字符串处理
自己不太会取名所以就学着ijkplayer取了ijktpl.js这样一个名字
快速入门
var $ = document.querySelector;
var tpl = $("#ijktpl");
var ijktpl = new IJKTPL(tpl, {
"title": "IJKTPL TITLE",
"content": "ITS IJKTPL CONTENT."
});
ijktpl.compile();
// 注意在主流浏览器里元素的id将会变成window属性!
// 也就是说上面的例子在全局作用域执行可能会失败!
基础语法
IJKTPL使用#{token}
用于格式化,如下
目前新版本优化以后不再使用以上语法了!
从v0.0.3开始使用[[token]]
用于格式化,如下
<!-- 旧版本 -->
<!-- Received the new message!
#{message} -->
<!-- 新版本 -->
Received the new message!
[[message]]
而条件判断则采用类C风格的三元表达式
<!-- 起始符号 [[?token]] -->
<!-- 否则符号 [[:token]] -->
<!-- 结尾符号 [[;token]] -->
<!-- 实例 -->
[[?title]]
<h2>[[title]]</h2>
[[:title]]
<h2>Welcome to IJKTPL</h2>
[[;title]]
类似C语言的三元运算符,title不为假则显示title的内容,否则显示默认的模板。
嵌套语法
[[?content]]
[[?title]]
<h2>[[title]]</h2>
<p>[[content]]</p>
[[:title]]
<h2>Welcome to IJKTPL!</h2>
<p>[[content]]</p>
[[;title]]
[[;content]]
迭代语法
0.0.2版本引入,用于代替使用选择器赋值。
<!-- 起始符号 [[^token1]] -->
<!-- 绑定符号 [[@token2]] -->
<!-- 结尾符号 [[$token1]] -->
<!-- 实例 -->
[[?posts]]
[[^posts]] [[@post]]
[[?post.content]]
[[?post.title]]
[[post.title]]
[[post.content]]
[[;post.title]]
[[;post.content]]
[[$posts]]
[[;posts]]
注意这里有个坑,参考下面的注意事项。
效率问题
要想了解性能问题得需要先了解IJKTPL的处理流程。
流程示意图:
- v0.0.2前(包括v0.0.2) 编译 -> 解析 -> 渲染 -> 解析 -> 渲染
- v0.0.3后(包括v0.0.3) 编译 -> 解析 -> 渲染 -> 渲染 -> 渲染
所以说呢?
1. IJKTPL大部分使用了标准库(或者说BIF)的字符串处理方法,性能上不会太差。
2. 影响性能的过程主要是在解析过程中。解析时会对分支多次检查,多次创建分支缓冲降低性能。
不跟没说一样么
v0.0.3后使用AST对模板进行了预解析,所以在复杂逻辑上性能提升非常明显。
注意事项
- IJKTPL可以自定义token前缀和后缀(参考下面)
- IJKTPL渲染过程为先分析逻辑分支后格式化token
- IJKTPL不支持使用大于号和小于号作为前缀和后缀
- options中的子options如果未设置都为false
- 是递归分析但并非递归下降分析(即嵌套不能使用重名变量)
关于最后一条。迭代会使用绑定的变量提前格式化代码,因此外部作用域的变量都是不可见的。
新版本的IJKTPL有自己的AST,每个迭代都有自己的作用域(不会提前格式化)。
FAQ与使用技巧
- 偶尔加载不完整的情况
可以设置一个自定义类,如下面的ijktpl-tpl
.ijktpl-tpl {
display: none;
}
将其属性设置为隐藏,然后在js中加载完毕后删除这个类即可。
function loadedCallback() {
var $ = document.querySelector;
$(".ijktpl-tpl").forEach((elem) => {
// 原生JS
elem.classList.remove("ijktpl-tpl");
// JQuery
//elem.removeClass("ijktpl-tpl");
});
}
提示:在HTML5标准中可以直接使用template标签,效果会比设置隐藏属性好一些:P。
无法格式化子级token
很抱歉目前没有实现。但是就这个问题本身而言并不是很难,之后的更新中会实现这一点。
浏览器兼容性
原文件是ES6风格编写的(因为喜欢箭头函数),但如果你使用ijktpl.min.js的话可以向下兼容到ES5标准。
- ES6
- ES5/ES3
- IE9+(保守)
IJKTPL结构树
- IJKTPL
- constructor(element, mapper, options)
- {Object} element
- {Object|Map} mapper
- {Object|Map} options
- {String} prefix
- {String} suffix
- {Boolean} debug
- {Boolean} useStrict(已弃用)
- {Object|Map} condition
- {String} prefix(已弃用)
- {String} suffix(已弃用)
- compile()
- N/A
- render(mapper)
- {Object|Map} mapper
- rebind(element, mapper, options)
- ...
- ...
- constructor(element, mapper, options)
为什么使用IJKTPL.JS?
- 相对的安全,不必担心数据泄露
- 绝对的轻量级,压缩以后不到5K(实际不到4K)
我编不下去了...
和Mustache模板的区别是什么呢?
区别应该不大。我自己没细看Mustache,写这个引擎之前我只看了点ejs的语法。。。
TODO:
实现一个批量生成方法repeat添加子token(token.key)的支持
授权许可
/*
* Copyright 2019 urain39 <urain39@qq.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/