Appearance
AnswerContainer
qxs-answer-container 是给旧答题页准备的运行时容器。
它接住 components-v2 时代的 list 数据结构,负责排序、补 titleIndex、按 examTypeEnum 分发题型,并继续暴露 onSubmit() / reset()。
如果你现在做的是新出题页,优先看 题目组件。
如果你手里是已经存在的问卷、病例答题或随访问卷页面,这个容器更适合做第一步迁移。
这是“先迁运行时”的入口
如果旧页面原来依赖的是 @qxs-bns/components-v2 里的 AnswerContainer,推荐先切到 qxs-answer-container,而不是一口气把整页改成单题组件直渲染。 完整替换对照见 Components 迁移指南,想直接照着改可以看 AnswerContainer 迁移速查。
基础用法
loading
ts
import '@qxs-bns/components/answer-container'如果你已经全量引入:
ts
import '@qxs-bns/components'主题
第一版保留了 default 和 case-practice 两个主题名,方便旧页面先迁移运行时结构,再慢慢收视觉。
loading
扩展交互
旧 AnswerContainer 里最难迁的是关系题入口和扩展渲染位。这一版已经补了 relation-exam-answer 和 answer-row-relation-exam-answer 对应的 renderer 属性。
loading
使用说明
list推荐通过.prop传入,保持对象和数组不被序列化。beforeChange也推荐通过.prop传入,返回false时可阻止当前题目的答题变更。type可控制文字题和填空题是否保持可编辑态。isShowProgress可在运行时标题区展示题目进度标签。showSingleRowScaleTitle可控制单行量表是否强制显示左侧标题列。onSubmit()会逐题收集当前提交结果,返回Promise<LegacyAnswerContainerItem[]>。reset()会清空容器内部的submitAnswer状态,但不会反向改写宿主原始数组。- 当前兼容题型:
single、multiple、blank_fill、sort、scale、text_fill。
宿主接入示例
loading
对齐到哪些旧页面
当前这批 demo 主要对齐的是 ksh-doctor 里这几类高频接法:
QuestionnaireDetailInfo.vueQuestionnaireDetailInfoPreview.vueNewVisitDetail.vueSceneExam/index.vuecase-practice/detail.vuecase-practice/exam-comment.vue
下面这些同类页面,当前也可以按同样的心智先迁移:
views/live/components/conditions-packet.vuecomponents/FirstAnswer.vue
这些场景的共同点是:
- 都是把旧
list直接交给容器 - 都依赖
disabled / isShowCorrect / themeName - 都可能带
type / isShowProgress / showSingleRowScaleTitle - 都会通过
ref.onSubmit()或只读回显来驱动宿主页面 - 部分页面对
beforeChange和@on-change很敏感
第一阶段还没覆盖的旧接口
这版运行时容器已经补回了大部分高频合同,但仍然不是旧 Vue 2 容器的逐像素复刻。当前先不要假设这些已经完全一样:
像 case-practice/case-answer.vue 这种依赖 relation-exam-answer 和命名 slot 的页面,目前还不属于“直接无感替换”的范围。
- 旧 Vue 2 slot 和现在的 renderer property 在实现方式上不完全等价。
- 关系题、讨论区、结果回显都已经有迁移入口,但宿主业务流程本身仍然需要页面层接管。
如果你的旧页面强依赖这些能力,建议先把 demo 和文档对齐当前运行时能力,再决定是继续补容器扩展点,还是下沉到单题组件处理。
Vue
vue
<script setup lang="ts">
import { ref } from 'vue'
import '@qxs-bns/components/answer-container'
const answerRef = ref<any>(null)
const questionList = ref([
{
examId: 1,
examIndex: 1,
examTypeEnum: 'single',
title: '请选择患者当前主要症状',
answers: [
{ examAnswerId: 11, answer: '胸闷' },
{ examAnswerId: 12, answer: '呼吸困难' },
],
},
])
async function handleSubmit() {
const result = await answerRef.value?.onSubmit()
console.log(result)
}
</script>
<template>
<qxs-answer-container
ref="answerRef"
:list.prop="questionList"
:before-change.prop="() => true"
/>
</template>原生 HTML
html
<script type="module">
import '@qxs-bns/components/answer-container'
const container = document.querySelector('qxs-answer-container')
container.list = [
{
examId: 1,
examIndex: 1,
examTypeEnum: 'text_fill',
title: '请填写本次复诊总结',
},
]
document.querySelector('#submit').addEventListener('click', async () => {
const result = await container.onSubmit()
console.log(result)
})
</script>
<qxs-answer-container></qxs-answer-container>
<button id="submit">提交</button>API
属性
| Name | Description | Type | Default |
|---|---|---|---|
list | 旧答题容器题目数组;支持单对象或数组 | LegacyAnswerContainerItem | LegacyAnswerContainerItem[] | [] |
theme-name | 运行时主题 | 'default' | 'case-practice' | 'default' |
type | 控制文字题 / 填空题是否保持可编辑态 | boolean | true |
disabled | 是否禁用答题交互 | boolean | false |
is-show-correct | 是否显示正确答案态辅助信息 | boolean | false |
is-show-bg | 是否给运行时选项增加背景态 | boolean | false |
is-show-progress | 是否显示运行时进度标签 | boolean | false |
show-single-row-scale-title | 单行量表时是否强制显示左侧标题列 | boolean | false |
beforeChange | 题目变更前拦截函数 | (row, answerItem?) => boolean | () => true |
answerRowRelationExamAnswerRenderer | 关系题扩展渲染器入口 | (context) => unknown | null |
方法
| Name | Description |
|---|---|
onSubmit() | 聚合当前容器内所有题目的提交结果 |
reset() | 重置当前容器内部答题态 |
addTitleNumber(list) | 对旧题目数组补 titleIndex |
事件
| Name | Description | Detail |
|---|---|---|
on-change | 任一题型运行时状态变化时触发 | 当前题目的最新运行时数据 |
relation-exam-answer | 关系题入口被触发时派发 | { action, answerItem, row } |
handleAction | 只读讲评区操作触发时派发 | { action, row } |
兼容字段
第一版重点兼容这些旧字段:
examIdexamIndexexamTypeEnumtitleIndexanswerssubmitAnswercustomBindsleastAnswerCountscaleQuestionListpageIndexexamAnswerResultsexamExpand