Custom
概述
Custom自定义字段组件,用lit 模板语法自由渲染任意输入界面,把多个原生控件(<input>、<textarea>等)的值聚合为一个状态值。适合邮箱前缀@域名、起止时间这类无法用单个内置 widget 表达的组合输入。
示例
声明一个自定义字段需要指定widget: 'custom',并实现renderContent渲染输入界面:
ts
const form = document.querySelector('#form');
form.state = {
email: configurable('admin@autostore.com', {
label: '电子邮件',
widget: 'custom',
renderContent: (values, html) => {
return html` <div style="padding:1em">
<label>
电子邮件:
<input .value=${values[0]} />
@<input .value=${values[1]} />
</label>
</div>`;
},
toState: (values) => values.join('@'),
toInput: (values) => values.split('@'),
}),
};loading
指南
工作原理
- 首先要实现
renderContent方法用于渲染自定义显示的内容,renderContent方法使用lit 模板语法。 Custom会监听inputSelectors匹配到的控件(默认为<input>标签)的input,change事件,当控件的值发生改变时,会调用toState函数,用于将控件的值转换为state的值,写入到状态中。由于控件可能有多个,所以传入toState(values)函数的是一个数组。- 当监听到
state的值发生改变时,会调用toInput方法,将状态值转换为适合控件的值,然后调用renderContent方法重新渲染。 - 当
dropdown=true时,renderSelection方法用于渲染值。
renderContent
renderContent方法用于渲染自定义组件内容。
renderContent方法接收两个参数:
- 第一个参数是当前字段数据(
values,是toInput返回的数组) - 第二个参数是
lit html模板方法,返回值是自定义组件内容。详见lit html
ts
form.state = {
email: configurable('admin@autostore.com', {
label: '电子邮件',
widget: 'custom',
renderContent: (values, html) => {
return html` <div style="padding:1em">
<label>
电子邮件:
<input .value=${values[0]} />
@<input .value=${values[1]} />
</label>
</div>`;
},
}),
};values是数组,依次绑定到<input>标签的.value属性即可。
renderSelection
当dropdown=true时,renderSelection方法用于在下拉触发器中渲染选择值:
ts
form.state = {
email: configurable('admin@autostore.com', {
label: '电子邮件',
widget: 'custom',
renderSelection: (values, html) => {
return html`<span style="color:red">${values.join('@')}</span>`;
},
}),
};使用方法同renderContent。
下拉展示
dropdown控制自定义内容的呈现方式,默认true以弹层方式显示,触发器中展示renderSelection渲染的值;false时自定义内容内联展示在表单中,此时renderSelection不再生效:
ts
form.state = {
email: configurable('admin@autostore.com', {
label: '电子邮件',
widget: 'custom',
dropdown: false,
}),
};inputSelectors
inputSelectors指定参与值收集的控件 CSS 选择器,默认'input,textarea'。所有匹配到的控件的值按 DOM 顺序组成数组,传给toState:
ts
form.state = {
email: configurable('admin@autostore.com', {
label: '电子邮件',
widget: 'custom',
inputSelectors: 'input',
}),
};属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
dropdown | boolean | true | 是否以下拉面板展示自定义内容 |
inputSelectors | string | "input,textarea" | 参与值收集的控件 CSS 选择器 |
renderSelection | function | 渲染下拉触发器中的值显示(dropdown=true时生效) | |
renderContent | function | 渲染自定义输入内容(lit 模板) |
注意事项
renderContent的values是数组(与toInput返回值同构),需按索引绑定到各控件;非数组状态值会被自动归一化为单元素数组。- 正在输入的控件在输入后的一帧内不会被程序性回写,以保证光标位置与连续输入不受影响。
dropdown=false时renderSelection不生效,字段值区域直接展示自定义内容。- 模板中的事件绑定、条件渲染均遵循 lit 模板语法,
.value属性绑定(lit 的受控回填写法)用于回填输入值。