Vue 接入
Vue 接入层的目标是让应用像使用普通表单组件一样使用 FormX,同时保留 Core 的独立能力。
当前推荐入口是 @formxjs/vue。它面向应用侧聚合了 Vue 运行时和 Element Plus 皮肤。
基础组件接入
vue
<script setup lang="ts">
import { ref } from 'vue'
import { FormX } from '@formxjs/vue'
import type { FormSchema } from '@formxjs/vue'
import '@formxjs/vue/style.css'
const formRef = ref<InstanceType<typeof FormX>>()
const model = ref({
name: '',
enabled: true
})
const schema: FormSchema = {
version: '1.0.0',
model: model.value,
fields: [
{ id: 'name', type: 'input', label: '名称', rules: [{ required: true }] },
{ id: 'enabled', type: 'switch', label: '启用' }
]
}
async function submit() {
const valid = await formRef.value?.validate()
if (!valid) return
console.log(formRef.value?.getValues())
}
</script>
<template>
<FormX ref="formRef" v-model:value="model" :schema="schema" />
<button type="button" @click="submit">提交</button>
</template>组件暴露 API
Vue 组件会暴露常用表单方法:
ts
await formRef.value?.validate()
await formRef.value?.validateField('name')
formRef.value?.resetFields()
formRef.value?.clearValidate()
formRef.value?.setValues({ name: 'demo' })
formRef.value?.setFieldValue('name', 'demo')
formRef.value?.getValues()
formRef.value?.getSubmitValues()
formRef.value?.getErrors()
formRef.value?.getFirstErrorPath()
formRef.value?.getFieldGroupAPI('rules')这些方法背后仍然是 Core 引擎。UI 层只负责把交互映射到 engine。
Dialog 和 Drawer
业务系统最常见的问题是:弹窗打开、详情接口返回、表单挂载、初始值重置之间的时序。
推荐模式是“会话化”:
ts
const visible = ref(false)
const loading = ref(false)
const formModel = ref({})
let sessionId = 0
async function openEdit(row: { id: string }) {
visible.value = true
loading.value = true
const current = ++sessionId
const detail = await fetchDetail(row.id)
if (current !== sessionId) return
formModel.value = detail
formRef.value?.setValues(detail, { replace: true })
loading.value = false
}
function close() {
sessionId++
visible.value = false
formRef.value?.resetFields()
}重点:
- 不要假设 Dialog 打开后
formRef已经立即存在。 - 详情返回要防止竞态。
- 整份详情回填用 replace 语义,局部修正才用 merge。
- 弹窗关闭后要让旧请求失效。
更多模式见 异步运行时。
自定义组件
自定义字段可以通过 custom 类型接入。schema 只保存组件标识,不保存组件实例。
ts
{
id: 'userPicker',
type: 'custom',
label: '用户',
component: 'UserPicker',
props: {
multiple: true
}
}运行时注册组件:
ts
const components = {
UserPicker
}vue
<FormX :schema="schema" :components="components" />自定义组件应该遵守 FormX 的字段协议:
- 接收当前值。
- 触发值变更。
- 支持 disabled、readOnly、loading、error 等状态。
- 不在组件内部私自维护与 engine 冲突的业务状态。
皮肤和默认入口
@formxjs/vue 是应用推荐入口:
ts
import { FormX } from '@formxjs/vue'如果你明确要使用 Element Plus 皮肤:
ts
import { FormXVueEp } from '@formxjs/vue-ep'如果你要实现自己的 Vue 皮肤,通常使用:
ts
import { useFormXEngine, useFormViewState } from '@formxjs/vue-core'再从 @formxjs/ui-core 获取中立视图模型。
Vue 接入建议
- 页面只关心业务数据和提交,不要把规则写回组件 watch。
- 远程选项、异步校验、级联请求走资源层。
- 弹窗编辑要处理挂载时序和竞态。
- 自定义组件只做交互和展示,不要绕开 engine 修改值。
- 如果业务需要设计器,schema 必须保持可序列化。