48-CommonQuery:零代码查询的实现

一行<CommonQuery :sqlId="'SYS_USER_s'" />渲染出完整的查询页——条件表单+结果列表+分页+导出。10.8KB的组件是"零代码模式"的唯一入口。这篇拆它怎么消费describe元数据自动生成一切,以及三种开发模式在这里的分界线。

源码:browise-vue/src/components/common/CommonQuery.vue(10.8KB)
协作:httpClient.describe / pageQuery、MetaGrid、form控件


一、组件的挂载流程

// CommonQuery.vue的setup(伪代码整理)
const props = defineProps<{ sqlId: string }>()

const center = useCenter()
const queryStore = center.addStore(props.sqlId + '_query')   // 查询条件store
const gridStore  = center.addStore(props.sqlId + '_grid')    // 结果store

const meta = ref<DescribeResult | null>(null)

onMounted(async () => {
  // ①拉元数据——整个组件的"图纸"
  const desc = await httpClient.describe(props.sqlId)
  meta.value = JSON.parse(desc)     // EaEngine.describe返回的是JSON字符串(第13篇)

  // ②条件store灌入元数据的conditions
  queryStore.meta = { conditions: meta.conditions }

  // ③首查
  await doQuery()
})

describe是一切的起点——conditions(第13篇的EA05查询条件元数据)变成查询表单、columns(EA03字段元数据)传给MetaGrid。组件自己没有任何硬编码的界面知识——界面完全由元数据描述。


二、条件表单:按conditions渲染

<template v-for="cond in meta.conditions" :key="cond.paramName">
  <!-- displayType决定控件 -->
  <TextBox   v-if="cond.displayType === 'text'"   v-model="queryParams[cond.paramName]" :label="cond.label" />
  <DateBox   v-if="cond.displayType === 'date'"   v-model="queryParams[cond.paramName]" :label="cond.label" />
  <NumberBox v-if="cond.displayType === 'number'" v-model="queryParams[cond.paramName]" :label="cond.label" />
  <!-- ComboBox:codeName有值挂字典 -->
  <ComboBox v-if="cond.displayType === 'select'" v-model="queryParams[cond.paramName]"
            :codeName="cond.codeName" :label="cond.label" />
</template>

describe.conditions的每个条目变一个控件——label做字段名、paramName做参数键、displayType选控件、codeName挂字典。operator决定控件形态(第13篇)——like是单值输入、>=/<=成对时渲染范围组件。

queryParams收集所有条件值——点查询时作为pageQuery的参数发给后端——EA05的动态条件按paramName匹配(第08篇:null跳过)——没填的条件后端自动忽略


三、结果列表:委托给MetaGrid

<MetaGrid
  :storeName="sqlId + '_grid'"
  :columns="meta.columns"
  pageUrl="/ea/page/' + sqlId"
  :exportOptions="['server', 'client', 'checked']"
/>

CommonQuery不自己渲染表格——columns元数据透传给MetaGrid(第47篇的模式2 store绑定+模式1分页混合)。组件复用的层级:CommonQuery = 条件表单(自己渲染)+ MetaGrid(结果区委托)+ 联动逻辑(查询按钮把queryParams传给gridStore触发加载)。


四、查询的完整链路

用户填条件点"查询"
  → doQuery()
     → gridStore.params = {...queryParams}
     → MetaGrid的server paging检测store变化(watch params)
        → httpClient.pageQuery(sqlId, params, page)
           → POST /ea/page/SYS_USER_s {psnName:"张", minRow:1, maxRow:50}
              → JwtAuthFilter → EaController → EaEngine.query
                 → 元数据拼SQL + 方言分页 + postProcess加密脱敏
              → {rows:[...], total:137}
        → gridStore.rowset.setData(rows)   → 表格更新

整条链没有任何一行业务代码——配置EA01-05五张表 → 界面自动存在。"零代码"的字面意义


五、CommonFormGrid:主从结构的变体

common/CommonFormGrid.vue——上表单下列表的主从联动版:表单选中行→下方列表按主键过滤。还有TreeQuery(左树右表)、CommonQueryDetail(19.2KB,查询+详情侧栏)——同一套元数据消费模式的四种布局变体

变体的本质——CommonQuery的挂载流程(describe→条件表单→grid→联动)不变,只有布局的模板变。如果要做第五种布局(比如双列表格),复制CommonQuery改template的排列即可——逻辑层已经固化


六、零代码的边界

CommonQuery覆盖标准查询页——但遇到这些就要退出零代码模式(第03篇的80/15/5):

需求退出方式
列渲染定制(状态列变tag)MetaGrid的#插槽(低代码)
行内编辑/主从联动CommonFormGrid或MetaGrid editable
业务校验复杂(跨字段/调接口)手写页面用useCenter/useBinding
表单布局复杂(多列/分组/嵌套)FormEditor设计器画

判断标准——界面结构是不是"条件+列表"的标准形。是→CommonQuery;不是但数据流标准→MetaGrid+store;连数据流都特殊→手写。三种模式的切换点是渐进的——describe元数据在三种模式间通用(都靠它拿字段定义)。


✅ 亮点:describe元数据驱动整个组件的渲染、conditions到控件的映射规则、queryParams与EA05动态条件的null跳过联动、组件复用层级(CommonQuery=条件表单+MetaGrid+联动)、四种布局变体共享逻辑层、零代码边界的判断标准。适合做元数据驱动UI的人。扩展方向:第13篇describe、第47篇MetaGrid、第03篇三种模式。

Logo

一站式 AI 云服务平台

更多推荐