base/CAPABILITY.md

20 KiB
Raw Blame History

@apigo.cc/base 能力清单 (Capability Specification)

一、 全局导出与生命周期行为

1. 导出与全局挂载

  • 模块导出index.js 重新导出了 http.js, ui.js, form.js, controls.js, list.js, nav.js, interaction.js 中的所有对象,以及来自 @apigo.cc/stateState
  • 全局命名空间挂载:在 window/globalThis 上挂载了 HTTP, UI, AutoForm, MouseMover, VirtualScroll, ApigoBase
  • 初始化自动刷新:页面加载时(DOMContentLoaded 或立即执行),对 document.documentElement 执行 RefreshState()

2. 退出拦截逻辑

  • 拦截触发条件:当 State.exitBlocks > 0 时,通过 window.addEventListener('beforeunload') 拦截页面刷新或关闭(调用 event.preventDefault())。

3. 主题自动适配

  • 逻辑行为:若 <html> 元素上既没有 data-bs-theme 也没有 $data-bs-theme,则自动注入属性: $data-bs-theme="LocalStorage.darkMode?'dark':'light'"

二、 HTTP 请求引擎 (HTTP)

1. 核心方法

  • HTTP.request(options) (异步)
    • 参数类型options: Object
      • url (String, 必填): 请求地址。
      • method (String, 可选): 默认 'POST'。会内部自动转为大写。
      • data (Any, 可选): 请求载荷。
      • headers (Object, 可选): 默认 {}
      • responseType (String, 可选): 'json' | 'binary' | 'text'。若未提供,将根据响应头 Content-Type 自动解析(含 application/json 解析为 'json',匹配图片/音视频/zip/pdf等解析为 'binary',其余解析为 'text')。
      • timeout (Number, 可选): 默认 10000 (ms)。基于 AbortSignal.timeout 实现。
    • 请求载荷 (data) 自动处理逻辑
      • dataHTMLFormElement,内部自动转换为 FormData
      • data 为普通对象,且其属性中包含 File, Blob, FileList 实例,内部自动转换为 FormData。其中,FileListArray 属性会依次 append 到相同 key 下,排除 undefined / null
      • 若数据最终为 FormData,则 自动删除 headers['Content-Type'](由浏览器自动设置 boundary
      • 若数据为普通对象且非二进制,且 headers 中无 Content-Type,则序列化为 JSON 字符串并自动添加 headers['Content-Type'] = 'application/json'
    • 返回值Promise<ResponseObject>,其结构为:
      {
        ok: Boolean,          // 请求是否成功 (status 在 200-299)
        status: Number,       // HTTP 状态码
        headers: Object,      // 响应头键值对
        responseType: String, // 实际解析后的响应类型 ('json' | 'binary' | 'text')
        result: Any,          // 响应数据主体
        error: String | null  // 错误信息 (若请求失败或 ok === false)
      }
      
  • 快捷方法 (内部包装 HTTP.request)
    • HTTP.get({ url, ...opt })
    • HTTP.post({ url, data, ...opt })
    • HTTP.put({ url, data, ...opt })
    • HTTP.delete({ url, ...opt })
    • HTTP.head({ url, ...opt })

三、 声明式数据组件 (<API>)

1. 响应式状态模型 (State)

  • request (读写): 映射请求参数。结构与 HTTP.request 参数一致: { url: '', method: 'GET', headers: {}, data: null, timeout: 10000, responseType: '' }
  • response (读写): 包含当前请求执行结果。结构为: { loading: false, ok: null, status: null, error: null, headers: {}, responseType: '', result: null }
  • result (读写): 响应结果快捷引用。当 response.result 为对象时,底层通过 Object.assign 合并更新;否则直接覆盖。

2. 编程接口方法 (Methods)

  • do(opt = {})
    • 用途:手动执行请求。
    • 参数opt 对象的字段(如 headers, data 等)会与 request 属性合并。
    • 控制参数opt.noui (Boolean)。若为 true,则在请求失败时不自动调用 UI.toast 弹窗。
    • 返回值Promise<ResponseObject>。若请求失败或接口返回 { error: ... }Promise 会抛出异常reject

3. 特殊逻辑行为

  • auto (Attribute) 若组件含有 auto 属性,且 request.url 非空,则深度监听 request 对象的变化。一旦变化会在下一微任务队列Promise.resolve())自动、异步触发 do()。有防抖机制,避免同一周期多次触发。

4. 事件派发

  • response:请求成功时触发。
    • bubbles: false
    • cancelable: false
    • detail: 完整的 ResponseObject 对象。
  • error请求失败网络错误、非2xx状态码、或返回数据中含 error 字段)时触发。
    • bubbles: true
    • cancelable: false
    • detail: Error 对象。

四、 万能表单系统 (<AutoForm>)

1. 容器属性 (Attributes)

  • vertical (Boolean): 开启垂直表单布局。
  • inline (Boolean): 开启无边框的流式行内布局(常用于顶部工具栏)。
  • nobutton (Boolean): 隐藏底部的默认提交/保存按钮。
  • api (String / Element): 绑定页面中 <API> 组件的 ID或直接为组件实例引用以便在提交时自动对接。
  • submitlabel (String): 自定义提交按钮的文本内容。默认为 "{#Submit#}"

2. 实例编程接口

  • data (读写): 表单内部数据的响应式 Proxy 模型(映射至 state.data)。可直接通过 Object.assign(form.data, newData) 或逐个属性赋值来修改表单中的值。
  • request (读写): 默认提交配置,默认为 { method: 'POST' }
  • response (只读): 提交请求返回的完整响应对象。
  • result (只读): 提交请求返回的 response.result
  • submit(opt = {})
    • 用途:手动触发表单校验与提交。
    • 校验逻辑:通过原生 form.reportValidity() 校验。若失败,调用 UI.toast 提示 "{#verify failed#}" 并退出。
    • 提交逻辑:如果绑定了 api 属性,则调用 api.do(req)(其中 req.data 自动绑定为表单 data);否则,如果配置了 request.url,则直接调用 HTTP.request(req);两者皆无则在控制台抛出警告。

3. Schema 项目 (FormItem) 结构定义

state.schema 数组中每一项可配置的字段:

  • name (String, 必填): 数据字段键名,与 form.data 中的属性双向绑定。
  • label (String, 可选): 表单项标签名称(仅在非 inline 模式下展示)。
  • type (String, 必填): 表单控件类型。
    • 原生支持:'text', 'password', 'email', 'number', 'date', 'datetime', 'file', 'select', 'checkbox', 'radio', 'switch', 'textarea'
    • 扩展注册支持:如 'DatePicker', 'ColorPicker', 'IconPicker', 'TagsInput'
  • if (String, 可选): 控制是否显示该表单项的条件表达式字符串。使用双重计算渲染($$if),其执行上下文中 this 指向 AutoForm 组件实例,可以通过 this.data 引用其他字段值。
  • setting (Object, 可选): 原生属性透传对象,会通过 $.="item.setting || {}" 绑定到控件上。
  • options (Array, 可选): 针对 select, checkbox, radio 类型。
    • 格式可以为扁平字符串数组:['Option1', 'Option2']
    • 也可以为键值对数组:[{ label: '选项1', value: 'val1' }]
  • placeholder (String, 可选): 仅对 select 类型有效,表示未选中时的禁用占位选项。
  • vertical (Boolean, 可选): 仅对 checkboxradio 类型有效。若为 true,各选项纵向排列;默认为 false(横向排列)。
  • text / label (String, 可选): 当 checkboxradio 未提供 options 选项时,使用此值作为单选项的标签,其选中时的值是 'on'

4. 插槽 (Slots)

  • actions:在表单底部提交按钮左侧的区域插槽(仅在非 inline 且非 nobutton 模式下渲染)。

5. 事件派发

  • submit:在开始提交数据前触发。
    • bubbles: false
    • cancelable: true(调用 event.preventDefault() 可彻底终止提交动作)
    • detail: 当前表单的数据对象 container.data
  • response:表单自动提交成功并得到接口响应后触发。
    • bubbles: false
    • cancelable: false
    • detail: 完整的响应对象 resp
  • error:提交失败(网络错、校验错或返回的 json 带有 error 字段)时触发。
    • bubbles: true
    • cancelable: false
    • detail: Error 对象。

6. 表单控件扩展机制 (AutoForm.register)

  • AutoForm.register(name, typeName)
    • 用途:将第三方/自定义 Web Component 注册为表单的自定义控件类型。
    • 参数
      • name (String): 组件标签名(如 'DatePicker')。
      • typeName (String, 可选): schema 中对应的 type 字符串。不传则默认等同于 name
    • 实现逻辑:当在 AutoForm 的 schema 中匹配到对应 type 时,自动在 DOM 树中插入该自定义组件,并将其属性 $. 绑定为 item.setting,其值 bind 双向绑定到 AutoForm 的对应数据字段。

五、 表单自定义扩展组件

1. 日期选择器 (<DatePicker>)

  • 核心能力:支持单日期选择,或双日期范围选择(主字段 + 影子字段模式)。
  • 启用范围选择:在 AutoForm 的对应 Schema 项目中,配置 setting.rangeEnd: "endFieldName";或在组件上直接配置 rangeEnd 属性。
  • 内部状态 (state)
    • start (String): 开始日期。
    • end (String): 结束日期。
  • 实例属性
    • value (读写): 映射至 state.start
    • isRange (只读): 根据是否配置了 rangeEnd 返回 Boolean 值。
  • 操作方法
    • updateStart(val): 更新 state.start 并分发 change 事件。
    • updateEnd(val): 更新 state.end,若处于 AutoForm 容器中,将该值同步写入到表单数据的 rangeEnd 对应字段中。
  • 事件派发
    • 'change':当主字段/开始日期发生改变时触发。
      • bubbles: true
      • detail: 改变后的开始日期字符串(state.start)。

2. 颜色选择器 (<ColorPicker>)

  • 核心能力:提供颜色取色器(type="color")与十六进制文本输入框的双向联动。
  • 内部状态 (state)
    • value (String): 颜色值,默认为 '#000000'
  • 实例属性
    • value (读写): 映射至 state.value
  • 方法
    • updateValue(val): 更新颜色状态并分发事件。
  • 事件派发
    • 'change':当值发生改变时触发。
      • bubbles: true
      • detail: 改变后的十六进制颜色字符串。

3. 图标选择器 (<IconPicker>)

  • 核心能力:基于 Bootstrap Icons 的可视化下拉搜索选择器。
  • 内部状态 (state)
    • value (String): 当前选中的图标名。
    • search (String): 图标搜索关键字。
    • open (Boolean): 下拉菜单的展开状态。
  • 实例属性
    • value (读写): 映射至 state.value
    • filteredIcons (只读): 经过 search 关键字过滤后的图标名称列表。
  • 方法
    • selectIcon(icon): 选中指定图标,收起下拉框并派发 change 事件。
    • toggle(): 切换下拉框展开状态。若展开,会自动延时聚焦在搜索输入框中。
  • 事件派发
    • 'change':当选中图标发生改变时触发。
      • bubbles: true
      • detail: 选中的图标类名。
    • 点击外部收起:监听全局 click 事件,点击外部自动收起下拉框;组件被移除 DOM 时自动注销该监听。

4. 标签输入框 (<TagsInput>)

  • 核心能力:可视化添加和删除标签。
  • 添加交互:在输入框中输入内容后,按 Enter, , (逗号) 或 (空格) 会自动将标签加入。
  • 删除交互:点击标签聚焦后,按 BackspaceDelete 键可将其移除,并自动聚焦到前一个标签。
  • 内部状态 (state)
    • tags (Array): 存储标签字符串的数组。
  • 实例属性
    • value (读写): 映射至 state.tags
  • 事件派发
    • 'change':当标签数组发生增删改变时触发。
      • bubbles: true
      • detail: 最新标签的字符串数组。

六、 增强列表组件 (<List>)

1. 列表布局模式 (mode Attribute)

  • normal (默认): 扁平列表模式。
  • group (分组):
    • 关联逻辑:通过 list 中成员的 groupfield 匹配 groups 数组中项的 groupidfield
  • tree (树形):
    • 关联逻辑:扁平化数组,通过每一项的 parentfield 匹配父项的 idfield。根项的值为空字符串 ''

2. 字段映射配置属性 (可重写默认值)

在组件初始化时,会调用 Util.updateDefaults 将以下属性更新为默认值:

  • idfield: 项的主键字段名,默认 'id'
  • labelfield: 项展示文本字段名,默认 'label'
  • summaryfield: 项辅助文本字段名,默认 'summary'
  • groupidfield: 分组的主键字段名,默认 'id'
  • grouplabelfield: 分组展示文本字段名,默认 'label'
  • groupsummaryfield: 分组辅助文本字段名,默认 'summary'
  • groupfield: 项关联分组的字段名,默认 'group'
  • parentfield: 树形下关联父节点的字段名,默认 'parent'
  • groupicon: 组/父节点的图标类,默认 'folder' (对应 Bootstrap Icons 的类名)。
  • itemicon: 项/叶子节点的图标类,默认 'file'

3. 功能属性 (Attributes)

  • fast (Boolean): 启用虚拟滚动。
    • 重要约束<List> 容器必须包含 Bootstrap 的 overflow-auto 类,且内置 style="overflow-anchor:none"(模板自带)。
  • collapsible (Boolean): 仅在 tree 模式下有效,开启树形节点的展开/收起能力。
  • auto-select (Boolean): 开启后,点击列表项时自动将该项的 id 记录至 state.selectedItem,如果重复点击则会置空。
  • auto-select-group (Boolean): 开启后,点击分组时自动将分组的 id 记录至 state.selectedGroup

4. 内部状态模型 (State)

  • list (读写): 原始列表数据数组。
  • groups (读写): 仅在 group 模式下使用,分组定义数组。
  • collapsed (读写): 仅在 treecollapsible 时使用,存储节点 ID 折叠状态的 Map Proxy。
  • selectedItem (读写): 当前选中的列表项 ID。
  • selectedGroup (读写): 当前选中的分组 ID。
  • _flatList (只读): 列表核心逻辑处理后的扁平化数组。
  • _renderedList (只读): 实际在 DOM 中遍历渲染的数组片段(若开启虚拟滚动,则只包含可视区切片)。

5. 插槽 (Slots)

  • item:列表单项渲染模板插槽。在自定义模板中,可以访问当前行数据 item 和索引 index
  • item-actions:行数据右侧按钮工具栏区域。
  • group-actions:分组数据行右侧按钮工具栏区域。

6. 虚拟滚动运行参数

  • 高度优先规则 若列表数据的某一项上配置了数字属性 _itemHeight,虚拟滚动引擎会将其作为该项的测量高度,直接跳过 DOM 的高度测量。

7. 事件派发

  • itemclick:点击列表项(非分组)时触发。
    • bubbles: false
    • detail: { item, index } (其中 index 为考虑虚拟滚动偏移量后的 绝对全局索引)。
  • groupclick:点击分组行时触发。
    • bubbles: false
    • detail: { item, index }

七、 导航组件 (<Nav>)

1. 结构与属性

  • vertical (Attribute, Boolean): 决定导航为垂直面板布局(带有右侧分割线)或水平导航栏布局(带底部阴影)。

2. 响应式数据模型 (State)

  • brand (Object, 可选): { image, icon, label },控制左上角/顶部的 Logo、图标及品牌文本。
  • list (Array, 必填): 导航栏项的数组。

3. 导航项结构(list 成员)

  • type: 决定导航项的渲染模式:
    • 'button': 导航按钮。
    • 'dropdown': 下拉菜单导航。含有 list (子项数组),子项类型可为:
      • 'button': 子项按钮。
      • 'switch': 状态开关。需要配置 bind (状态Proxy引用) 和 name (要绑定的字段名)。
      • 水平布局下可以通过 width (Number) 控制下拉菜单宽度,默认 250
    • 'fill': 弹性填充块(flex-fill),用于实现右对齐等布局。
  • name (String): 导航标识。当点击导航按钮时,该 name 会自动被写入 Hash.nav 以同步 URL 哈希。
  • label (String): 文本展示。
  • icon (String): 图标类名(基于 Bootstrap Icons
  • noselect (Boolean, 可选): 若为 true,点击该项仅派发点击事件,不会 修改 Hash.nav

4. 事件派发

  • nav:点击任何菜单项或下拉子菜单项时触发。
    • bubbles: false
    • detail: { item } (被点击的导航项数据定义)。

八、 拖拽改变大小组件 (<Resizer>)

1. 组件属性

  • vertical (Attribute, Boolean): 为 true 时,鼠标为 row-resize,调整高度;默认调整宽度。
  • min (Attribute, Number): 像素下限,默认 10
  • max (Attribute, Number): 像素上限,默认 1000
  • target (Element): 要调整大小的目标 DOM 元素。默认是组件的前一个兄弟节点 (container.previousElementSibling)。

2. 事件与双向绑定

  • bind (输入拦截): 支持通过绑定表达式传入像素值(数字),自动设置为 target 的 width/height
  • resizing:拖动调整大小的过程中持续触发。
    • bubbles: false
    • detail: { oldSize, newSize }
  • resize:拖动结束时触发。
    • bubbles: false
    • detail: { oldSize, newSize }
  • change:拖动结束时触发,输出最终的大小数值。常用于将新尺寸写回全局 State
    • bubbles: false
    • detail: newSize (Number)

九、 编程交互工具集 (UI)

1. 核心对话框方法 (UI.showDialog)

  • UI.showDialog({ title, message, buttons, type })
    • 参数
      • title (String, 可选): 对话框标题。
      • message (String, 必填): 提示消息,支持 HTML 标记($html 渲染)。
      • buttons (Array, 可选): 按钮文字数组,默认 ['{#Close#}']
      • type (String, 可选): 主题类型 'primary' | 'danger' | 'warning' | 'success' 等,控制边框、标题及最后一个主按钮的颜色。
    • 返回值Promise<Number>
      • 点击按钮返回其索引值 (从 1 开始)。
      • 点击关闭图标或按 ESC 取消返回 0

2. 快捷对话框

  • UI.alert(message, options):包装 UI.showDialog
  • UI.confirm(message, options):确认框。
    • 默认按钮:['{#Cancel#}', '{#Confirm#}']
    • 返回值:Promise<Boolean> (选中确认按钮为 true,取消为 false)。

3. 轻提示方法 (UI.toast)

  • UI.toast(message, options)
    • 参数
      • message (String, 必填): 消息文本。
      • options (Object, 可选)
        • delay (Number): 自动关闭延迟时间(毫秒),默认 5000。若传入 0 则永久不消失。
        • type (String): 主题背景色 'primary' | 'success' | 'danger' | 'warning' 等。
        • buttons (Array): 自定义 Toast 内嵌按钮,点击会设置 result = index + 1 并在点击后自动 dismiss。
        • container (String): 目标 Toast 容器 ID默认 'default'

4. 快捷 Toast 确认

  • UI.toastConfirm(message, options)
    • 弹出带有一个 Confirm 按钮的 Toast。
    • 返回值:Promise<Boolean>(点击确认按钮返回 true,其余情况返回 false)。