指令
指令
即为在html元素开标签内编写的自定义属性,类似于Vue
及Angular
中的指令
。语法为<element #exTag="value">
,用它可以封装一些实用功能,目的是写更少的代码去做更多的事情。在NornJ
中,指令
实质上是标签
的一种特殊写法:
<div #show="{false}"></div>
完全等价于:
<div>
<#props>
<#show>
{false}
</#show>
</#props>
</div>
内置指令
目录
show
类似于Vue
的v-show
指令,#show
用于切换元素是否显示,原理为修改style:
const html = nj`
<div #show="{{isShow}}">
test inline extension tag
</div>
`({ isShow: false });
console.log(html); //<div style="display:none">test inline extension tag</div>
mobx-bind
类似于Vue
的v-model
指令,可以使用#mobx-bind
配合Mobx
在<input>
及<textarea>
等表单元素上创建双向数据绑定
,它会根据控件类型自动选取正确的方法来更新元素。
- 在线示例(jsfiddle)
基本使用方法
import { Component } from 'react';
import { observable } from 'mobx';
import nj from 'nornj';
class TestComponent extends Component {
@observable inputValue = '';
render() {
return nj`
<input :#mobx-bind="inputValue">
`(this);
}
}
如上所示,无需编写<input>
标签的onChange
事件,inputValue
变量已自动和<input>
标签建立了双向数据绑定
的关系。点这里是一个#mobx-bind
结合表单组件的示例页面。
- 实质上,
#mobx-bind
的实现原理和v-model
很类似,上述示例其实就是下面的语法糖形式:
class TestComponent extends Component {
@observable inputValue = '';
@autobind
onChange(e) {
this.inputValue = e.target.value;
}
render() {
return nj`
<input value={inputValue} {onChange}>
`(this);
}
}
#mobx-bind
和#mst-bind
存放在nornj-react
包中,需要按如下方式引入后方可使用:
import 'nornj-react/mobx';
另外如果使用nornj-loader
,则需要在Webpack
的配置中引入相应的扩展配置文件
:
module: {
rules: [
{
test: /\.t.html(\?[\s\S]+)*$/,
use: [{
loader: 'nornj-loader',
options: {
outputH: true,
delimiters: 'react',
extensionConfig: require('nornj-react/mobx/extensionConfig')
}
}]
},
...
]
}
onChange
事件
由于#mobx-bind
默认自动设置了组件的onChange
事件,但有些情况下我们可能还是需要在onChange
中做一些其他的操作:
class TestComponent extends Component {
@observable inputValue = '1';
@autobind
onChange(e) {
console.log(e.target.value);
}
render() {
return nj`
<input :#mobx-bind="inputValue" {onChange}>
`(this);
}
}
如上所示,onChange
事件的行为和标签原生的onChange
完全相同,它会在文本框的值变化后执行。
- 使用
action
更新变量
在mobx
开发中如果启动严格模式或者使用mobx-state-tree
时,则须要使用action
来更新变量。可按下面方式配置使用action
:
import { observable, action, configure } from 'mobx';
// don't allow state modifications outside actions
configure({enforceActions: true});
class TestComponent extends Component {
@observable inputValue = '1';
@action.bound
setInputValue(v) {
this.inputValue = v;
}
render() {
return nj`
<input :#mobx-bind.action="inputValue">
`(this);
}
}
当有action
修饰符时,#mobx-bind
会默认执行camel命名法(set + 变量名
)定义的action
,上例中为setInputValue
。
mst-bind
#mst-bind
即为#mobx-bind
的默认使用action
来更新值的版本,用来配合mobx-state-tree
的变量使用:
store:
import { types } from "mobx-state-tree";
const TestStore = types.model("TestStore",
{
inputValue: '1'
})
.actions(self => ({
setInputValue(v) {
self.inputValue = v;
}
}));
component:
@inject('rootStore')
@observer
class TestComponent extends Component {
render() {
return nj`
<input :#mst-bind="testStore.inputValue">
`({
testStore: this.props.rootStore.testStore
});
}
}
如上,#mst-bind
会默认执行camel命名法(set + 变量名
)定义的action
来更新值,上例中为setInputValue
。除此外#mst-bind
的其他特性与上述的#mobx-bind
完全相同。
目前mobx-bind和mst-bind默认支持的控件列表
控件名称 | 控件类型 | 备注 |
---|---|---|
<input> |
原生 | <input type="checkbox"> 和<input type="radio"> 暂时不支持 |
<textarea> |
原生 | |
<select> |
原生 | <select multiple> 暂时不支持 |
<ant-input> |
Ant Design | |
<ant-input.textarea> <ant-textarea> |
Ant Design | |
<ant-checkbox> |
Ant Design | |
<ant-checkbox.group> <ant-checkboxgroup> |
Ant Design | |
<ant-radio.group> |
Ant Design | |
<ant-switch> |
Ant Design | |
<ant-select> |
Ant Design | <ant-select mode="multiple"> 暂时不支持 |
<ant-cascader> |
Ant Design | |
<ant-datepicker> <ant-datepicker.monthpicker> <ant-datepicker.weekpicker> <ant-datepicker.rangepicker> <ant-monthpicker> <ant-weekpicker> <ant-rangepicker> |
Ant Design | |
<el-input> |
Element-React | |
<el-select> |
Element-React | <el-select multiple> 暂时不支持 |
<el-datepicker> |
Element-React | |
<el-daterangepicker> |
Element-React | |
<el-timeselect> |
Element-React | |
<el-timepicker> |
Element-React | |
<el-timerangepicker> |
Element-React | |
<el-switch> |
Element-React | |
<el-checkbox> |
Element-React | |
<el-checkbox.group> |
Element-React | |
<el-radio.group> |
Element-React | |
<el-cascader> |
Element-React |