Appearance
题目组件
@qxs-bns/components 的题目体系已经去容器化。
宿主自己维护题目数组、题型入口、分页和业务状态,题目组件只负责渲染、编辑、校验和导出题目本体。
基础用法
推荐做法是由宿主自己渲染题目数组,并按题型切换不同的单题组件。
Vue 宿主请优先使用 .prop
数组、对象、布尔值和函数请使用 .prop 透传,例如 :answer-list.prop="item.answers"、:show-analysis.prop="true"、:upload-image.prop="uploadFn"。
如果写成 show-analysis="false",Web Component 仍然会把它当成真值属性。
宿主管理题目与提交数据
loading
推荐让宿主直接维护最终提交数据,并通过 pageIndex 反推分页边界渲染。
这样页面底部看到的数据就是提交 payload;运行时 helper 只需要在提交前统一执行 validate(),必要时再从当前 DOM 回收 toJSON() 结果。
分页边界不会进入最终导出
qxs-page-end 只参与页码计算和页面分段,不会出现在最终题目数组里。
默认显示策略
四个单题组件默认都隐藏解析和副文本,即 show-analysis=false、show-rich-text=false。
只有外部显式传入这些字段时,解析区或副文本能力才会显示。
单题型文档
| 题型 / 模块 | 说明 | 文档 |
|---|---|---|
| 选择与排序题 | 单选、多选、排序题,以及互动问答单选/多选 | QxsSubjectSingle |
| 填空题 | 根据题干中的填空位维护答案组 | QxsBlankFill |
| 问答题 | 维护关键词、答题设置和参考答案 | QxsTextFill |
| 量表题 | 维护量表列和问题行 | QxsScale |
| 分页 / 排序 / helper | qxs-page-end、qxs-subject-sortable 和 runtime helpers | 运行时与辅助组件 |
公共 API
公共属性
下表适用于四个单题组件:qxs-subject-single、qxs-blank-fill、qxs-text-fill、qxs-scale。
| 名称 | 说明 | 类型 | 默认值 |
|---|---|---|---|
title | 题干内容 | string | '' |
answer-list | 题目答案列表 | any[] | [] |
rich-text-content | 题目副文本 HTML | string | '' |
analysis | 解析内容 | string | '' |
is-edit | 是否进入编辑态 | boolean | false |
show-action | 是否显示底部操作区 | boolean | true |
subject-prefix | 题号前缀。未传时按 order-index 自动生成;传空字符串时隐藏题号 | string | internal |
show-analysis | 是否显示解析编辑区 | boolean | false |
show-rich-text | 是否整体启用副文本能力 | boolean | false |
hide-add-rich-text | 是否隐藏“添加题目描述(图文)”入口 | boolean | false |
show-delete-action | 是否显示内置删除按钮 | boolean | true |
show-save-action | 是否显示内置完成编辑按钮 | boolean | true |
公共事件
| 名称 | 说明 | Detail |
|---|---|---|
save | 点击内置“完成编辑”后触发 | toJSON() 导出的题目数据 |
delete | 点击内置“删除”后触发 | null |
update:modelValue | 仅在开启 use-model 的题型上触发 | 当前题干内容 |
公共插槽
| 名称 | 说明 | 适用范围 |
|---|---|---|
action | 自定义底部操作区。通常配合 show-delete-action=false、show-save-action=false 使用 | all subject components, qxs-page-end |
business-tag | 题目标题旁的宿主业务标签区 | single / blank-fill / text-fill / scale |
sub-text | 接管题目副文本编辑区;未传时回退为组件库内置富文本实现 | single / blank-fill / text-fill / scale |
公共方法
| 名称 | 说明 | 类型 |
|---|---|---|
validate() | 返回当前题目校验错误列表 | () => SubjectError[] |
toJSON() | 导出当前题目数据 | () => Promise<any> |
运行时 Helper
| 名称 | 说明 | 类型 |
|---|---|---|
collectSubjectElements(root) | 从宿主容器收集所有题目组件和分页边界 | (root: ParentNode) => SubjectElement[] |
validateSubjectElements(elements) | 汇总执行每个元素的 validate() | (elements: Iterable<SubjectElement>) => { valid: boolean; errors: SubjectError[] } |
serializeSubjectElements(elements) | 当宿主没有直接维护提交态数据时,汇总执行每个元素的 toJSON(),并自动换算 pageIndex | (elements: Iterable<SubjectElement>) => Promise<any[]> |
insertPageBreak(items, index?) | 在指定位置插入分页符 | (items: SubjectLikeItem[], index?: number) => SubjectLikeItem[] |
removePageBreak(items, customId) | 按 customId 删除分页符 | (items: SubjectLikeItem[], customId: string) => SubjectLikeItem[] |
rebuildPageBreaksFromPageIndex(items) | 把带 pageIndex 的题目数组恢复成带分页边界的渲染数组 | (items: SubjectLikeItem[]) => SubjectLikeItem[] |
serializeSubjectsWithPageIndex(items) | 把渲染数组中的分页符换算成真实题目的 pageIndex | (items: SubjectLikeItem[]) => SubjectLikeItem[] |
getPaginationMeta(items) | 获取每个分页符对应的页码信息 | (items: SubjectLikeItem[]) => PaginationMeta[] |