vue-formless

Vue 3 表单组合式 hooks
648
Install
npm install vue-formless
Latest Version:0.2.0
Vue:3
License:MIT
Last Updated:Oct 14, 2026
Links: GitHub  ·  npm
Maintainer: xuyimingwork

vue-formless

简体中文 | English

Vue 3 表单组合式库:控件表 + FormView,布局与输入拆开。当前 0.2.0,0.x 期间 API 仍可能调整。

同一套混合布局:左边手写 Element Row/Col/Item,右边 <User.*> + 嵌套 FormView 换密度。

混合布局代码对照

Playground 平铺对比(布局对齐):

混合布局平铺对比

pnpm add vue-formless
# 或 npm i vue-formless

peer:vue ^3.3。

用法

项目里绑一次宿主(无官方 Element 适配包):

import { ElCol, ElForm, ElFormItem, ElInput, ElRow } from 'element-plus'
import { defineComponent, h, ref, type PropType } from 'vue'
import { createFormFields, createFormView, type FormFieldFormless } from 'vue-formless'

declare module 'vue-formless' {
  interface FormFieldCustomOptions {
    label?: string
  }
}

// ElFormItem 的 `prop` 用点分路径;内核位置(`buyers[0].name`)由本层编码(design.md §20.9)。
// 一个宿主 `prop` 装不下多个口 → 多口一格不绑宿主(`undefined`),
// 需要宿主校验就用 `fl:field="wrap-embed"` 拆成一格一口。
function toItemProp(prop: FormFieldFormless['prop']): string | undefined {
  if (prop == null || prop.length !== 1) return undefined
  const [location] = prop
  if (location == null) return undefined
  const dotted = location.replace(/\[(\d+)\]/g, '.$1').replace(/^\./, '')
  if (!dotted || /[[\]]/.test(dotted)) return undefined // 编不出来:不绑宿主
  return dotted
}

// 无前缀的写口 `modelValue` 按 no-prefix 规则透传到宿主 Form,而 ElForm 的 model
// 口叫 `model`:适配层用一个 MyForm 包住 ElForm 完成映射,并把 ElForm 实例的
// validate / resetFields 透出给 FormView 的 ref 代理。工厂不再接受 form.props 函数。
const MyForm = defineComponent({
  inheritAttrs: false,
  props: { modelValue: { type: [Object, Array] as PropType<unknown>, default: undefined } },
  setup(props, { attrs, slots, expose }) {
    const form = ref<Record<string, unknown> | null>(null)
    expose(new Proxy({}, {
      get: (_, key) => {
        const inner = form.value
        if (inner == null) return undefined
        const value = Reflect.get(inner, key, inner)
        return typeof value === 'function' ? value.bind(inner) : value
      },
      has: (_, key) => form.value != null && key in form.value,
    }))
    return () => h(ElForm, { ...attrs, ref: form, model: props.modelValue }, slots)
  },
})

export const FormView = createFormView({
  layout: { Row: ElRow, Col: ElCol, props: { column: 2 } },
  form: { component: MyForm },
  item: {
    component: ElFormItem,
    props: (fl: FormFieldFormless) => ({
      label: fl.label,
      prop: toItemProp(fl.prop),
    }),
  },
})

export const User = createFormFields({
  name: { label: '姓名', component: ElInput },
})
<FormView ref="formRef" v-model="form" fl:layout label-width="96px">
  <User.Name />
  <User.Name layout-item:span="max" />
</FormView>

validate() / resetFields() 走 FormView 的 ref(代理内层 Form)。栅格细节见 docs/adr。

在线 Playground

GitHub Pages(仓库需在 Settings → Pages → Source 选 GitHub Actions,推 main 后生成):

本地预览打包结果:PAGES_BASE=/vue-formx/ pnpm build:pages,再用任意静态服务器打开 site/。

仓库结构

packages/vue-formless              # 内核(npm:vue-formless)
packages/layout                    # 内部栅格,打进内核 dist
playground                         # Element Plus 基线 vs Formless
playground-layout                  # 24 格布局工作台
docs/adr.md                        # 架构决策(单篇汇总)

开发

pnpm i
pnpm dev          # 启动 playground
pnpm build        # 构建库
pnpm test
pnpm typecheck

Playground 对照:基础表单、筛选条、只读详情、混合布局、DateRange。

pnpm playground
# http://localhost:5173
pnpm playground:layout
# http://localhost:5174

License

MIT

Related Packages

@resourge/vue3-hook-form

vue3-hook-form is a simple and basic controlled hook form. Aiming to create form...

7,170 1
@lunarxyz/core

The JS-SDK of Lunarxyz App, provides simple APIs to operate.

2,610
@gooonzick/wizard-vue

Vue 3 integration for Wizard framework

3,248 3
@schema-element-editor/host-sdk

Schema Element Editor (SEE) 插件宿主接入 SDK,支持 React/Vue/纯 JS

9,323 2
@adbros/vue-validation

Composable for schema-based form validation in Vue 3 using Valibot

6,036 0

Version History

Version Released Vue License
0.2.0 ^3.3.0 MIT
0.1.1 ^3.3.0 MIT
0.1.0 ^3.3.0 MIT
0.0.1 ^3.3.0 MIT