增强React开发体验
NornJ模板引擎在React开发中是JSX的一个很好的替代或辅助工具,下面的是一个使用cdn上umd包的在线可运行实例:
- 在线Playground(jsfiddle)
安装
npm install nornj
npm install nornj-react
npm install nornj-loader # webpack环境请一起安装此包
在js文件中使用NornJ模板
每个React组件都须要在render返回组件的标签代码,如在HelloWorld组件中渲染一个下拉框,用JSX和NornJ的语法分别实现:
- JSX
export default class HelloWorld extends Component {
render() {
return (
<div className="hello" style={{ width: 300, height: 200 }}>
<input type="text" />
<select>
{[1, 2, 3].map((item, i) => i > 1
? <option>{item + 1}</option>
: <option>{item}</option>
)}
</select>
</div>
);
}
}
- NornJ
import nj, { template as t } from 'nornj';
import 'nornj-react';
export default class HelloWorld extends Component {
render() {
return t`
<div class="hello" style="width:300px;height:200px;">
<input type="text">
<select>
<#each {[1, 2, 3]}>
<#if {@index > 1}>
<option>{@item + 1}</option>
<#else><option>{@item}</option></#else>
</#if>
</#each>
</select>
</div>
`;
}
}
如上例,NornJ可使用ES6+的tagged template literals语法在js文件中描述模板,模板语法也直接支持处理各种逻辑,并且更贴近于html规范。
更多关于在js文件中编写
NornJ模板的语法细节请参考这里。
NornJ和JSX相互嵌套使用
如果您不想完全使用NornJ替代JSX,那么NornJ也可以成为JSX的一个很好的辅助工具,例如可以使用NornJ的if及each等语法替代JSX中的三目运算符与map。
- 使用
if替代三目运算符:
import nj, { template as t } from 'nornj';
import 'nornj-react';
export default class HelloWorld extends Component {
render() {
return (
<div>{t`
<#if ${this.props.isButton}>
${<button>click me</button>}
<#else>${<input type="text" />}</#else>
</#if>
`}</div>
);
}
}
- 使用
each替代map:
import nj, { template as t } from 'nornj';
import 'nornj-react';
export default class HelloWorld extends Component {
render() {
return (
<div className="hello" style={{ width: 300, height: 200 }}>
<input type="text" />
<select>{t`
<#each {1 .. 10}>
<#if {@index > 1}>
#${({ item, index }) => <option>{item + 1}</option>}
<#else>#${({ item, index }) => <option>{index}</option>}</#else>
</#if>
</#each>
`}</select>
</div>
);
}
}
如上所示,NornJ与JSX的语法并不会发生冲突,可共存一起运行。这样即使无需修改您已有的代码,也可使用NornJ模板带来的各种语法糖。
如果在嵌套时
JSX需要获取NornJ模板内产生的变量,如上例的#each中,这时可以使用NornJ提供的访问器属性语法获取,具体参考这里。
在单独的文件中编写NornJ模板
NornJ模板除了可以在js文件中编写之外,还可以编写在单独的模板文件中,用来做组件(或页面)展现层与结构层的分离(具体文档请参考这里)。例如编写一个helloWorld.t.html文件:
<template name="helloWorld">
<div class={styles.hello}>
<select>
<#each {[1, 2, 3]}>
<#if {@index > 1}>
<option>{@item + 1}</option>
<#else><option>{@item}</option></#else>
</#if>
</#each>
</select>
</div>
</template>
然后可以在js文件中引入后使用:
import tmpls from './helloWorld.t.html';
export default class HelloWorld extends Component {
render() {
return tmpls.helloWorld(); //执行模板函数生成标签
}
}
如上,每个*.t.html文件内都可以定义一个或多个template标签。
这些template标签会在引用它的js文件中通过nornj-loader进行解析,生成一个以template标签的name属性为key的模板函数集合对象,在各个组件的render中调用它们就会生成相应的标签。
直接在JSX中使用
NornJ也提供了一个可以直接在JSX中编写的babel插件,写法如下:
const Button = () => {
return (
<div>
<for i={0} to={10}>
<if condition={i < 5}>
<i>less than 5</i>
<else>
<i>greater than 5</i>
</else>
</if>
</for>
</div>
)
}
具体请见babel-plugin-nornj-in-jsx。
与各种React已有生态结合
NornJ模板可直接支持所有React现有生态,包括Redux、React-Router、Mobx、Ant Design等等,它可以和任何已有的React生态共存。