vdt.js v0.3.2
Vdt.js
vdt is short for virtual-dom template
Vdt.js
is a template engine based on virtual-dom technology.
It is inspired by React/virtual-dom,
and uses JSX as template syntax.
See TodoMVC implemented by Vdt.js
Features
- Just the ui. Just the template further more. But more powerful than common template.
- Virtual-dom. Diff update unlike Handlebars/mustache.js.
- Lightweight. Rewrite a compiler instead of jstransform. Discard ES6 syntax sugar and JS analysis, so it's faster.
- Template can be extended.
<t:parent>
<b:section>
- Easy to use. You can use it with any other js library, such as jQuery. See vdt-todomvc
Install
npm install vdt.js --save
Example
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>vdt template engine demo</title>
</head>
<body>
<script type="text/vdt" id="template">
var a = 1, // this is a
showInfo = function(index, name) {
alert('Click ' + index + ' ' + name);
}
<div class="users">
<input id="add" value={input} /> input: {input}
<ul>
{/* output users */}
{users.map(function(user, index) {
return <li class="user" id={user.id} ev-click={
// use es5's bind or underscore's bind to pass arguments
showInfo.bind(null, index, user.name)
// or closure
/*function() {
showInfo(index, user.name);
}*/
}>{index}: {user.name}</li>
})}
</ul>
{/* custom attributes */}
<div attributes={{'data-a': a, input: input}} id={a} ev-dblclick={function() {console.log('Dblclick')}}>this is a({a})</div>
</div>
</script>
<script type="text/javascript" src="../dist/vdt.js"></script>
<script type="text/javascript">
var data = {
users: [
{name: 'John', id: '1'},
{name: 'Javey', id: '2'},
{name: 'Tom', id: '3'},
{name: 'Sarah', id: '4'}
],
input: ''
};
var str = document.getElementById('template').innerHTML,
vdt = Vdt(str),
dom = vdt.render(data);
document.body.appendChild(dom);
var input = document.getElementById('add');
input.addEventListener('input', function(e) {
data.input = e.target.value;
vdt.update(data);
});
input.addEventListener('change', function(e) {
data.users.push({name: e.target.value, id: data.users.length});
data.input = '';
vdt.update(data);
});
</script>
</body>
</html>
Custom attributes
See vnode.md
You can write template like this to render custom attributes directly.
<div attributes={{'data-a': a, input: input}} id={a}>this is a({a})</div>
Notice
UseclassName
instead ofclass
in html.All html tags must be closed. e.g.<input />
.- Use
{/* comment */}
instead of<!-- comment -->
. It is just Javascript comment which is wrapped by{}
. The last html element will be returned. You must wrap all html in a element. e.g.
<div> <h1>title</h1> <div>body</div> </div>
instead of
<h1>title</h1> <div>body</div>
The second one will return only one element
<div>body</body>
.
Express middleware
Take vdt as a express middleware.
app.use(require('vdt.js').middleware({
src: 'vdt/src/path',
amd: true, // and amd wrapper
force: false, // force compile
autoReturn: true // see api of `Vdt` below
}));
Escape & Unescape
Any output will be escaped. If you want prevent it, you can do it likes below:
var a = '<h1>title</h1>';
<div>{a}</div> // a will be escaped, -> <div><h1>title</h1></div>
<div innerHTML={a}></div> // a will not be escaped -> <div><h1>title</h1></div>
Event
You can bind event in vdt
template directly by adding ev-event
property, likes below:
<ul>
{/* output users */}
{users.map(function(user, index) {
return <li className="user" id={user.id} ev-click={
// use es5's bind or underscore's bind to pass arguments
showInfo.bind(null, index, user.name)
// or closure
/*function() {
showInfo(index, user.name);
}*/
}>{index}: {user.name}</li>
})}
</ul>
Template Extend
Vdt template can be extended. Use <t:templateFunction>
and <b:block>
directive.
Use <t:templateFunction>
to extend the parent template function. templateFunction
is a function of parent template.
Use <t:block
> to set block which can be filled by child.
Use parent()
to get parent content.
<script type="text/vdt" id="parent">
<div className="card">
<div className="head">{title}</div>
<b:body>
<div>parent body</div>
</b:body>
<b:footer>
<div>parent footer</div>
</b:footer>
</div>
</script>
<script type="text/vdt" id="child">
// You can also compile it in node, then require it by require.js
var parent = Vdt.compile(document.getElementById('parent').innerHTML);
<t:parent title="child card title">
<b:body>
<div>child body</div>
</b:body>
<b:footer>
{parent()}
<div>child footer</div>
</b:footer>
</t:parent>
</script>
Api
Vdt(source, options)
Compile source
then return a vdt object.
- @param
source
{String|Function} JSX template source or a template function returned byVdt.compile
- @param
options.autoReturn=true
{Object|Boolean} If addreturn
keyword at end or not. The last element of template have to be ahtml tag element
if istrue
. - @return {Object} a vdt object
Vdt.compile(source, options)
Compile JSX template source then return a template function which should pass to Vdt
.
The returned function has a property named source. You can use it to pre-process JSX.
- @param
source
{String} JSX template source - @param
options.autoReturn=true
{Object|Boolean} If addreturn
keyword at end or not. The last element of template have to be ahtml tag element
if istrue
. - @return {Function} a template function should pass to
Vdt
.
template.source
The source code of template function.
The vdt
object
The object returned by Vdt
.
vdt.render(data)
Handle data and return a dom.
- @param
data
{Object} data passed to template @paramthisArg
{Object} the binding of this in template.this
isdata
in template.- @return {Dom} html dom
vdt.update(data)
Update the dom using the new data.
- @param
data
{Object} the whole data passed to template. If it is not provided,vdt.data
will be used. - @return {Dom} html dom which has updated
vdt.data
The data passed to vdt above. So you can modify it directly.
Vdt.parse(source)
Parse JSX template to an ast object
- @param
source
{String} JSX template source - @return {Object} abstract syntax tree object
Vdt.stringify(ast)
Stringify the ast object to hscript string.
- @param
ast
{Object} abstract syntax tree object - @return {String} hscript string with a return expression at end
Vdt.virtualDom
The object exported by virtual-dom module.
Benchmark
See Benchmark
Render(compile every time)
- Vdt.js#render x 5,454 ops/sec ±2.40% (89 runs sampled)
- Lodash#render x 2,390 ops/sec ±3.68% (81 runs sampled)
- Underscore#render x 6,035 ops/sec ±5.86% (81 runs sampled)
- Handlebars#render x 959 ops/sec ±6.16% (77 runs sampled)
- Mustache#render x 4,899 ops/sec ±6.09% (84 runs sampled)
Fastest is Underscore#render
Update(cache compiled result)
- Vdt.js#update x 14,724 ops/sec ±3.61% (87 runs sampled)
- Lodash#update x 7,734 ops/sec ±2.70% (84 runs sampled)
- Underscore#update x 7,989 ops/sec ±4.52% (89 runs sampled)
- Handlebars#update x 7,200 ops/sec ±2.63% (86 runs sampled)
- Mustache#update x 7,747 ops/sec ±2.40% (96 runs sampled)
Fastest is Vdt.js#update
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago