npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@leiyin/v-form-renderer

v1.0.2

Published

Base on element-ui, Render form-item easily

Readme

@leiyin/v-form-renderer

一个基于 Vue 3 + Element Plus 的配置化表单渲染组件,用 JSON/Schema 快速生成复杂表单。

✨ 特性

  • 配置驱动(Content Schema)
  • 支持 group 嵌套、动态显隐与禁用
  • v-model 双向绑定与方法暴露
  • 远程选项加载与自定义组件
  • 完整 TypeScript 类型与 ESM/CJS 构建

📦 安装

  • peerDependencies:vue ^3.2.0、element-plus 2.11.7
pnpm add @leiyin/v-form-renderer
# 或
npm install @leiyin/v-form-renderer
# 或
yarn add @leiyin/v-form-renderer

🚀 基础用法

<template>
  <VFormRenderer :content="schema" />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import VFormRenderer from '@leiyin/v-form-renderer'

const schema = ref([
  { id: 'username', type: 'input', label: '用户名', el: { placeholder: '请输入' }, default: '' },
  { id: 'role', type: 'select', label: '角色', options: [
    { label: '管理员', value: 'admin' },
    { label: '普通用户', value: 'user' }
  ] }
])
</script>

🔗 v-model 与方法

  • v-model:使用 v-model:model 绑定整个表单对象
  • 方法暴露:通过 ref 获取实例并调用内置方法
<template>
  <VFormRenderer
    v-model:model="form"
    :content="schema"
    ref="formRef"
    @enter="onEnter"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import VFormRenderer, { type VFormRendererInstance } from '@leiyin/v-form-renderer'

const form = ref<Record<string, any>>({})
const formRef = ref<VFormRendererInstance>()

const onEnter = () => {
  // 回车事件
}

const getValue = () => {
  const result = formRef.value?.getFormValue() // outputFormat 后的值
  console.log(result)
}

const validate = async () => {
  const ok = await formRef.value?.validate()
  console.log('valid:', ok)
}

const reset = () => {
  formRef.value?.resetFields()
}

const patch = () => {
  formRef.value?.updateForm({ username: '张三' })
}
</script>

方法来源与实现参考:

⚙️ Props

  • content: Content[] 必填,表单 Schema
  • labelWidth: string,统一 label 宽度,默认 98px
  • disabled: boolean,禁用整个表单
  • inline: boolean,行内表单,默认 true
  • readonly: boolean,只读模式(input 显示文本,select 显示 label)
  • 透传:支持 Element Plus el-form 的其余属性与事件(使用 v-bind="$attrs")

🧩 Content Schema

类型定义参考 form.ts

常用字段:

  • id: string,唯一键,作为数据 key
  • label: string | Function,表单项标题;支持组件函数
  • type: string,例如 'input' | 'select' | 'radio-group' | 'checkbox-group' | 'cascader' | 'group'
  • el: Record<string, any>,对应组件的属性,如 placeholder、multiple 等
  • default: any,初始默认值
  • items: Content[],当 type='group' 时的子项
  • hidden(formValue, item): boolean,返回 true 隐藏
  • disabled(formValue, item): boolean,返回 true 禁用
  • options: { label: string; value?: any }[],选择类组件选项
  • component: 自定义组件,优先于 type 的内置组件
  • inputFormat(obj): any,处理输入值(default/v-model/updateForm)
  • outputFormat(val, obj): any,处理输出值(getFormValue 时应用)
  • rules: FormItemRule[],Element Plus 校验规则
  • remote: 远程 prop/选项加载(select/radio/checkbox 支持自动映射)
  • on: 事件监听回调,签名为 (args, updateForm, setOptions) => void

示例:group 嵌套

const schema = [
  {
    id: 'user',
    type: 'group',
    label: '用户信息',
    items: [
      { id: 'name', type: 'input', label: '姓名', default: '' },
      { id: 'age', type: 'input', label: '年龄', el: { type: 'number' } }
    ]
  }
]

🌐 远程选项加载

const schema = [
  {
    id: 'city',
    type: 'select',
    label: '城市',
    remote: {
      // 返回 Promise 的方法(可传入 params)
      url: (params) => fetch(`/api/cities?kw=${params.kw}`).then(r => r.json()),
      dataPath: 'data.list',   // 响应体中数据路径
      label: 'name',           // 用作 label 的字段
      value: 'code'            // 用作 value 的字段
    }
  }
]

当为 select/radio-group/checkbox-group 时,远程数据会自动映射为 Element Plus 的选项。 实现参考 RenderFormItem.vue

👁️ 只读与显隐

  • readonly: true 时,input 显示文本、select 显示选中项 label
  • hidden/disabled:传入函数,依据当前 formModel 动态控制
const schema = [
  {
    id: 'level',
    type: 'select',
    label: '级别',
    options: [{ label: 'A', value: 'A' }, { label: 'B', value: 'B' }]
  },
  {
    id: 'extra',
    type: 'input',
    label: '额外信息',
    hidden: (form) => form.level !== 'A'
  }
]

🎯 校验与重置

  • 使用 Element Plus 的规则校验(rules)
  • validate(): Promise<boolean | void>
  • resetFields(): 重置为 default 值并清除校验

参考 useFormEvents.ts

🧱 插槽与自定义

  • 命名插槽:以 id 为名注入内容,例如 #id:username
  • label 组件:将 label 设置为组件/函数,渲染自定义标题
  • 自定义组件:传入 component 替代内置 Element Plus 组件
<template>
  <VFormRenderer :content="schema">
    <template #id:username>
      <span style="margin-right: 8px">用户名扩展内容</span>
    </template>
  </VFormRenderer>
</template>

<script setup lang="ts">
const schema = [
  {
    id: 'username',
    type: 'input',
    label: '用户名',
    el: { placeholder: '请输入' }
  }
]
</script>

插槽实现参考 v-form-renderer.vue 与渲染器 render-component.ts

📚 导入与类型

  • 默认导出:VFormRenderer
  • 类型导出:Content、VFormProps、VFormRendererInstance 等

入口参考 index.ts