超好用的指令模板引擎
- 超小体积(gzip之后只有4K)
- 支持dom指令系统
- 良好的兼容性,兼容ie8及现代浏览器,兼容node环境
- 避免输出的xss漏洞
- 高性能dom渲染引擎
- 与AngularJS指令兼容
- 自定义指令和前缀
npm install --save sodajs
- https://unpkg.com/sodajs@0.4.10/dist/soda.min.js
- https://unpkg.com/sodajs@0.4.10/dist/soda.js
- https://unpkg.com/sodajs@0.4.10/dist/soda.node.min.js
- https://unpkg.com/sodajs@0.4.10/dist/soda.node.js
version | soda | soda.node |
---|---|---|
Mordern Browsers | ✓ | ✓ |
Mobile Browsers | ✓ | ✓ |
ie | ≥8 | ≥9 |
node | ✗ | ✓ |
dom解析引擎 | 原生 | 自带nodeWindow引擎 |
提示: ie 8兼容需要自行引入es5-shim 或es5-sham 和console-polyfill
查看这里的ie8的兼容测试
- script标签
<script src="https://unpkg.com/sodajs@0.4.10/dist/soda.min.js"></script>
- 使用webpack
import soda from "sodajs"
let soda = require('sodajs/node');
低版本node可以使用dist版本
let soda = require('sodajs/dist/soda.node')
var tpl = '<div>{{name}}</div>';
document.body.innerHTML = soda(tpl,{ name : 'soda' })
➜ 示例
var data = {
name: 'soda',
info: {
version: '2.0'
}
}
soda("{{info.version}}", data);
// result => "2.0"
soda("{{info.foo.foo1}}", data)
// result => "" without errors
soda("{{info['name']}}", data)
// result => "2.0"
var data = {}
soda("{{1 + 2}}", data);
// result => 2
soda("{{true ? 'soda' : 'foo'}}", data)
// result => "soda"
soda("{{1 < 3 && 'soda'}}", data)
// result => "soda"
➜ 示例
var data = {
list: [
{list: [{'title': '<>aa</h1>'}, {'title': 'bb'}], name: 0, show: 1},
{list: [{'title': 0 }, {'title': 'bb'}], name: 'b'}
]
};
soda('{{list[list[0].show === 1 ? list[0].name : 1].list[0].title}}', data)
// result => '<>aa</h1>'
var data = { name : 'soda',show: true };
soda(` <div soda-if="show">Hello, {{name}}</div>
<div soda-if="!show">I\'m hidden!</div>`,
data
)
// result => <div>Hello, soda</div>
➜ 示例
soda-repeat="item in array"
soda-repeat="item in object"
soda-repeat="item in array by index"
soda-repeat="item in object by key"
soda-repeat="(index, value) in array"
soda-repeat="(key, value) in object"
默认的下标是$index
var tpl = '\
<ul>\
<li soda-repeat="item in list" soda-if="item.show">\
{{item.name}}\
{{$index}}\
</li>\
</ul>'
var data = {
list: [
{name: "Hello" ,show: true},
{name: "sodajs" ,show: true},
{name: "AlloyTeam"}
]
};
document.body.innerHTML = soda(tpl, data);
➜ 示例
soda.filter(String filterName, Function func(input, args...)) {{input|filte1:args1:args2...|filter2:args...}}
example:
soda.filter('shortTitle', function(input, length){
return (input || '').substr(0, length);
});
var tpl = '\
<ul soda-repeat="item in list">\
<li class="title">\
{{item.title|shortTitle:10}}\
</li>\
</ul>'
document.body.innerHTML = soda(tpl,{ list : [
{title:'short'},
{title:'i am too long!'}
] })
➜ 示例
输出原始的html,不做完全转换
var tpl = '<div soda-html="html"></div>'
document.body.innerHTML = soda(tpl,{ html : '<span style="color:red;">test soda-html</span>' })
用html替换当前结点
var tpl = '<div soda-replace="html"></div>'
document.body.innerHTML = soda(tpl,{ html : '<span style="color:red;">test soda-html</span>' })
div will be replaced with given html div会被html替换
嵌套模板
soda-include="tmplateName:arg1:arg2:..." 和soda.discribe一起使用
var data = {
name: "soda"
};
// define sub template named tmpl1
soda.discribe('tmpl1', `<h1>{{name}}</h1>`);
// use template tmpl1 by soda-include
soda(`<span soda-include="tmpl1">1</span>`, data);
// result => <h1>dorsy</h1>
// set compile false not to compile sub template
soda.discribe('tmpl1', `<h1>{{name}}</h1>`, {
compile: false
});
// show origin template
soda(`<span soda-include="tmpl1">1</span>`, data);
// result => <h1>{{name}}</h1>
soda.discribe('tmpl2', function(path){
return `<h1>{{name}}_${path}</h1>`;
});
soda(`<span soda-include="list3:sub{{'path' + 1}}">1</span>`, data);
// result => <h1>soda_subpath1</h1>
// In node env
soda.discribe('tmplNode', function(path){
return fs.readFileSync(path, 'utf-8');
});
soda(`<span soda-include="tmplNode:view.html">1</span>`, data);
// result => view.html Tmplate
soda-class="currItem === 'list1' ? 'active' : ''"
soda-src="hello{{index}}.png"
soda-style="style"
data example:
var data = { style : { width : '100px', height : '100px' } };
soda-rx="{{rx}}%"
soda-checked="{{false}}"
如果值为false 或者 "", 该属性就会被移除,否则,会被添加上去
改变指令的前缀,默认的前缀是soda-
soda.prefix('v:')
var tpl = '\
<ul>\
<li v:repeat="item in list" v:if="item.show">\
{{item.name}}\
</li>\
</ul>'
var data = {
list: [
{name: "Hello" ,show: true},
{name: "sodajs" ,show: true},
{name: "AlloyTeam"}
]
};
document.body.innerHTML = soda(tpl, data);
自定义指令
soda.directive('name', {
priority: 8,
// how to compile el
link({ scope, el, parseSodaExpression, expression, getValue, compileNode, document }) {
}
});
- scope: 当前的scope数据
- el: 当前节点
- expression: 指令的表达式原始字符串
- getValue: 从data链式获取值
getValue({a: {b: 1}}, "a.b"); // ===> 1
- parseSodaExpression: 解析soda表达式
parseSodaExpression('{{1 + 2 + a}}', {a: 1}); // ===> 4
- compileNode: 继续编译节点
- document: 使用document参数而不是使用window.document, 这样可以在node环境下去用
soda.directive('mydirective', {
priority: 8,
link({ scope, el, parseSodaExpression, expression, getValue, compileNode, document }) {
var value = parseSodaExpression(expression);
if(value){
var textNode = document.createTextNode(value);
el.appendChild(textNode);
}
}
}
soda(`
<div soda-mydirective="add one tips: {{tips}}"></div>
`, {
tips: 'tips'
});
// result ==> <div>add one tips: tips</div>
自定义node端的dom解析引擎
soda.node版本的默认dom解析引擎是nodeWindow,你可以用这个方法替换为jsdom等
var document = require('document');
var soda = require('soda');
soda.setDocument(document);
// ... run
git clone
git clone git://github.com/AlloyTeam/sodajs.git
安装依赖
npm install
然后执行npm start
npm start
执行run build构建代码
npm run build
soda使用mocha来做自动化测试
测试单元在test目录
npm run test
兴趣部落, QQ群, 群活动
Copyright (c) 2015-present, AlloyTeam