Skip to content

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

指南 ​

工作原理 ​

  1. 首先要实现renderContent方法用于渲染自定义显示的内容,renderContent方法使用lit 模板语法。
  2. Custom会监听inputSelectors匹配到的控件(默认为<input>标签)的input,change事件,当控件的值发生改变时,会调用toState函数,用于将控件的值转换为state的值,写入到状态中。由于控件可能有多个,所以传入toState(values)函数的是一个数组。
  3. 当监听到state的值发生改变时,会调用toInput方法,将状态值转换为适合控件的值,然后调用renderContent方法重新渲染。
  4. 当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 的受控回填写法)用于回填输入值。