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 🙏

© 2024 – Pkg Stats / Ryan Hefner

vue-smart-antdv

v1.0.28

Published

vue ant-design-vue element virtual smart form register multiplex dynamic custom component

Downloads

10

Readme

Vue | Ant-Design-Vue | Elment-plus Project

组件说明

 基于 Ant-Design-Vue/Elment-plus 组件的上层简化封装,抹平平台代码差异,只需关注组件的逻辑编写,支持组件一切原有api。
 SmartForm 智能动态表单组件,用 virtual form 数据形式描述组件,实现数据动态配置化生成组件,支持普通数据格式、纯html模板片段、组件及集合hooks混合形式配置,在保证快速编写生成便捷性的同时,保留自定义开放性。
 可以自定义注册一套符合自己系统的FormType组件显示,实现配置与组件的分离、复用。
 智能快速生成对应表单,并支持自定义显示修改表单项内容、语言国际化等,供项目使用。
 开发时只需关注业务数据实现、无需关注组件本身,对应的form数据配置可以在多处复用、灵活便捷修改。
 可以结合服务端使用,将显示内容控制交给服务端。

Getting Started

Install dependencies,

$ npm i vue-smart-antdv

$ yarn add vue-smart-antdv

使用例子如下

SmartForm 基于 Ant-Design-Vue, SmartFormEl 基于 Elment-plus 可根据项目库使用情况对应选择组件

  import { SmartForm, SmartFormEl } from 'vue-smart-antdv'

主要配置参数 支持透传使用全部的 Form 组件相关属性 参数

  formType: 指定使用的Form表单元组件元素 不传默认使用Input组件
  formProps: 组件 Form 的所有 props 都会被透传给 Form 组件
  itemProps: 透传配置给 form-item 
  comProps: 透传配置给 form-item 内的对应表单,如 Input、Select 等元素

formType 支持显示的 Form 表单组件 自定义注册扩展组件例子在下面 - 不传默认显示使用 Input 组件类型

  自定义辅助组件:
  rowText// 块文本
  Label// 只显示 label 文本
  CustomCom// 自定义显示内容组件带label
  PlainText// 纯文本
  Divider// 分隔线组件

  内置支持的表单组件:
  Input// 输入框
  InputNumber// 数字输入框
  Password// 密码框
  TextArea// 文本域
  Select// 下拉框
  Search// 搜索框
  Switch// 开关
  Radio// 单选框
  Checkbox// 多选框
  DatePicker// 让去洗澡去
  MonthPicker// 月份选择器
  RangePicker// 范围选择器
  Rate// 评分
  Slider// 滑懂输入条
  Cascader// 级联选择请
  AutoComplete// 自动完成
  TreeSelect// 树选择器

最简单的使用方式 如下一段简单配置数据即可生成一个 Input 组件的表单元素 virtual form 形式描述

const dataConfig = [
 {
    itemProps: {
      label: 'label文本',
      name: 'input',
    },
  },
]

// jsx
<SmartForm config={dataConfig} init={formState}></SmartForm>

// vue
<SmartForm :config='dataConfig' :init='formState'></SmartForm>

hook编写并结合其它hook如useHttp动态获取数据,高频公共组件根据需要在需要复用的地方直接引入对应动态hook表单配置项复用

// useFormItem.jsx
import useHttp from '@/hooks/useHttp';
const getSelectList = async () => {} 

export const useSelectForm = props => {
  // select 下拉框数据源配置
  // 可以动态替换修改表单项 label 类型等,复用hook
  const selectList = useHttp(getSelectList);

  return {
    formType: 'Select',
    itemProps: {
      label: 'Select',
      name: 'select',
    },
    comProps: {
      options: selectList,
    },
  };
};
// FormPage.jsx
import { useSelectForm } from '@/hooks/useFormItem';

const selectForm = useSelectForm();

const dataConfig = [
  selectForm,
]

// jsx
<SmartForm config={dataConfig} init={formState}></SmartForm>

// vue
<SmartForm :config='dataConfig' :init='formState'></SmartForm>

普通数据配置数据源

const treeData = [
  {
    title: 'tree1',
    value: 'tree1',
    id: 'tree1',
    children: [
      {
        title: 'tree1-1',
        value: 'tree1-1',
        id: 'tree1-1',
        children: [
          {
            title: 'tree1-1-1',
            value: 'tree1-1-1',
            id: 'tree1-1-1',
          },
          {
            title: 'tree1-1-2',
            value: 'tree1-1-2',
            id: 'tree1-1-2',
          },
        ],
      },
      {
        title: 'tree2',
        value: 'tree2',
        id: 'tree2',
      },
    ],
  },
]

export const dataConfig = [
  {
    formType: 'Divider',
    comProps: {
      dashed: true,
      orientation: "right",
      children: "SmartForm!",
    },
  },
  {
    formType: 'Divider',
  },
  {
    itemProps: {
      label: 'input',
      name: 'input',
    },
    comProps: {
    },
  },
  {
    formType: 'Password',
    itemProps: {
      label: 'password',
      name: 'password',
    },
    comProps: {
    },
  },
  {
    formType: 'TextArea',
    itemProps: {
      label: 'textarea',
      name: 'textarea',
    },
    comProps: {
    },
  },
  {
    formType: 'InputNumber',
    itemProps: {
      label: 'inputNumber',
      name: 'inputNumber',
    },
    comProps: {
      min: "1", 
      max: "80", 
    },
  },
  {
    flexRow: 1,
    formType: 'Select',
    itemProps: {
      label: 'select',
      name: 'select',
    },
    comProps: {
      class: '',
      options : [
        {
          label: '客户',
          value: '客户',
        },
        {
          label: '业务员',
          value: '业务员',
        },
      ],
    },
  },
  {
    flexRow: 1,
    formType: 'Search',
    itemProps: {
      label: 'search',
      name: 'search',
    },
    comProps: {
      mode: "multiple",
      multiple: true, // el
      options : [
        {
          label: '客户',
          value: '客户',
        },
        {
          label: '业务员',
          value: '业务员',
        },
      ],
    },
  },
  {
    formType: 'Switch',
    itemProps: {
      label: 'switch',
      name: 'switch',
    },
    comProps: {
    },
  },
  {
    formType: 'Radio',
    itemProps: {
      label: 'radio',
      name: 'radio',
    },
    comProps: {
      options: [
        {
          label: 'radioGroup a',
          value: 'a',
        },
        {
          label: 'radioGroup b',
          value: 'b',
        },
      ]
    },
  },
  {
    formType: 'Checkbox',
    itemProps: {
      label: 'checkbox',
      name: 'checkbox',
    },
    comProps: {
      options: [
        {
          label: 'checkbox a',
          value: 'a',
        },
        {
          label: 'checkbox b',
          value: 'b',
        },
      ]
    },
  },
  {
    formType: 'DatePicker',
    itemProps: {
      label: 'datePicker',
      name: 'datePicker',
    },
    comProps: {
    },
  },
  {
    formType: 'MonthPicker',
    itemProps: {
      label: 'monthPicker',
      name: 'monthPicker',
    },
    comProps: {
    },
  },
  {
    formType: 'RangePicker',
    itemProps: {
      label: 'rangePicker',
      name: 'rangePicker',
    },
    comProps: {
    },
  },
  {
    formType: 'Rate',
    itemProps: {
      label: 'rate',
      name: 'rate',
    },
    comProps: {
    },
  },
  {
    formType: 'Slider',
    itemProps: {
      label: 'slider',
      name: 'slider',
    },
    comProps: {
      marks: {
        0: 'A',
        20: 'B',
        40: 'C',
        60: 'D',
        80: 'E',
        100: 'F',
      },
    },
  },
  {
    formType: 'Cascader',
    itemProps: {
      label: 'cascader',
      name: 'cascader',
    },
    comProps: {
      options: [
        {
          value: 'zhejiang',
          label: 'Zhejiang',
          children: [
            {
              value: 'hangzhou',
              label: 'Hangzhou',
              children: [
                {
                  value: 'xihu',
                  label: 'West Lake',
                },
              ],
            },
          ],
        },
        {
          value: 'jiangsu',
          label: 'Jiangsu',
          children: [
            {
              value: 'nanjing',
              label: 'Nanjing',
              children: [
                {
                  value: 'zhonghuamen',
                  label: 'Zhong Hua Men',
                },
              ],
            },
          ],
        },
      ],
    },
  },
  {
    formType: 'AutoComplete',
    itemProps: {
      label: 'autoComplete',
      name: 'autoComplete',
    },
    comProps: {
    },
  },
  {
    formType: 'TreeSelect',
    itemProps: {
      label: 'treeSelect',
      name: 'treeSelect',
    },
    comProps: {
      treeData,
      data: treeData,
    },
  },
]

组件直接传入 普通数据配置数据源 引入、调用

import { SmartForm } from 'vue-smart-antdv'

// form 组件绑定初始数据值
const formStateObj = {
  input: '15160208888',
  inputNumber: 8,
  password: '666',
  textarea: 'textarea',
  select: 'usa',
  search: ['业务员'],
  switch: false,
  radio: 'b',
  radioGroup: 'b',
  checkbox: ['a', 'b'],
  // datePicker: undefined,
  // monthPicker: undefined,
  // rangePicker: undefined,
  rate: 2.5,
  slider: 80,
  cascader: ['zhejiang', 'hangzhou', 'xihu'],
  autoComplete: 'Downing Street',
  treeSelect: 'parent 1-0',
  customCom: 'CustomComzyb',
  formItemInput: 888,
  text: 'text文本',
  radioGroup2: 'b',
}
const formState = reactive(formStateObj);

const useFormConfig = useForm()

<SmartForm {...props} config={dataConfig} init={formState}></SmartForm>

jsx hooks 式配置使用

import { ref, onMounted, } from 'vue';

const useForm = (config = {}) => {
  const varLabel = ref('varLabel')
  setTimeout(() => {
    varLabel.value = '动态Label'
  }, 5000)
  
  // 当配置项里需要使用到初始数据的变量时,如 自定义formItem数据、自行绑定 或 使用数据进行展示等时,配置项需要写成函数形式 可以接收到 form 的formState数据
  return ({formState} = {formState: {}}) => ([
    // 复用普通数据配置
    ...dataConfig,

    // 修改显示内容
    {
      flexRow: 1,
      formType: 'Search',
      itemProps: {
        label: varLabel.value,
        name: 'searchTest',
      },
      comProps: {
        mode: "multiple",
        'vModel': formState['search'],
        tagRender: (p) => {
          return <a-tag color="orange" style="margin-right: 3px">
            { p.label }&nbsp;&nbsp;
          </a-tag>
        },
        options : [
          {
            label: '客户',
            value: '客户',
          },
          {
            label: '业务员',
            value: '业务员',
          },
        ],
      },
    },
    
    {
      noRule: true,
      formType: 'CustomCom',
      CustomCom: <div>自定义组件</div>,
      // 写成函数形式 可以接收到 form 的formState数据
      children: ({formState}) => (<>
        <div>自定义组件children</div>
        <a-form-item name="customcom" >
          <a-input v-model={[formState['customcom'], 'value']} />
        </a-form-item>
      </>),
      itemProps: {
        label: 'CustomCom',
        name: 'customCom',
      },
    },

    // 原标签代码形式 灵活自定义显示
    <div class='divCom'>
      vnode
      <a-tag color="red">red</a-tag>
    </div>,
    <a-form-item name="formItemInput" label="formItemInput" rules={[{ required: true, message: 'Please pick an item!' }]}>
      <a-form-item name="formItemInput" >
        <a-input-number vModel={[formState['formItemInput'], 'value']} min="1" max="10" />
      </a-form-item>
      <span class="ant-form-text">bbb</span>
    </a-form-item>,
    <a-form-item name="radioGroup2" label="radioGroup2">
      <a-radio-group v-model={[formState['radioGroup2'], 'value']} >
        <a-radio value="a">item 1</a-radio>
        <a-radio value="b">item 2</a-radio>
        <a-radio value="c">item 3</a-radio>
      </a-radio-group>
    </a-form-item>,
    <a-form-item name="text" label="text">
      <span class="ant-form-text">texttext</span>
    </a-form-item>,
  ])
};

export default useForm;

jsx hooks 式配置使用

import { SmartForm } from 'vue-smart-antdv'

export default defineComponent({
  setup(props, ctx) {
    return () => {
      const useFormConfig = useForm()
      return <SmartForm :config='useFormConfig' :init='formState'></SmartForm>
    } 
  }
});

vue hooks template 式配置使用

<template>
  <SmartForm :config='useFormConfig' :init='formState'></SmartForm>
</template>

import { SmartForm } from 'vue-smart-antdv'

const useFormConfig = useForm()

自定义注册一套符合自己系统的FormType组件显示

import { ref, defineComponent, reactive, } from 'vue';
import { SmartForm } from 'vue-smart-antdv'// 

// 注意 需要写成如下组件形式 才能有自己的数据值 改变值才可以起效
const CountComp = defineComponent({
  setup(props, ctx) {
    const count = ref(0)
    const add = () => {
      count.value++
    }
    return () => {
      return <button onClick={add}>{count.value}</button>
    } 
  }
});

const SmartFormCustom = (props) => {
  // 自定义注册组件内容,函数形式 接收 formState 对应Form组件的model数据 可自行绑定 或 使用数据进行展示
  const registerComp = ({formState}) => {
    return ({
      CustomTextFormItem: <div className={`CustomFormItem`}>
        CustomFormItem 自定义显示组件元素 - {formState.input} 
      </div>,
      CustomCountFormItem: <div className={`CustomFormItem`}>
        CustomFormItem 自定义显示组件元素 - {formState.password} - <CountComp></CountComp>
      </div>,
    }) 
  }
  return <SmartForm {...props} registerComp={registerComp}></SmartForm>  
}

export default defineComponent({
  setup(props, ctx) {
    return () => {
      const formStateObj = {
        input: "15160208888",
        password: "666",
      }
      const formState = reactive(formStateObj);

      const config = ({formState}) => [
        {
          noRule: true,  
          formType: 'CustomTextFormItem',
          itemProps: {
            label: 'CustomTextFormItem',
            name: 'CustomTextFormItem',
          },
          comProps: {
          },
        },
        {
          noRule: true,  
          formType: 'CustomCountFormItem',
          itemProps: {
            label: 'CustomCountFormItem',
            name: 'CustomCountFormItem',
          },
          comProps: {
          },
        },
        {
          noRule: true,  
          formType: 'CustomCountFormItem',
          itemProps: {
            label: 'CustomCountFormItem2',
            name: 'CustomCountFormItem2',
          },
          comProps: {
          },
        },
        {
          itemProps: {
            label: 'input',
            name: 'input',
          },
          comProps: {
          },
        },
        {
          formType: 'Password',
          itemProps: {
            label: 'password',
            name: 'password',
          },
          comProps: {
          },
        },
      ]

      return <SmartFormCustom config={config} init={formState}></SmartFormCustom>
    } 
  }
});

自定义注册FormType组件例子

显示效果

image

支持修改SmartForm内部定义配置 目前支持: comDefProps、getLabel、rules

// 全部引入
import * as SmartAntd from 'vue-smart-antdv'
SmartAntd.(comDefProps、getLabel、rules)
// 或者按需引入 部分需要修改的配置
import { 需要的配置项 } from 'vue-smart-antdv'

// 自定义修改后要显示的配置 或者部分修改
const 自定义的配置项 = {
  ...comDefProps,
}

// template 修改配置
<SmartForm :配置项='自定义的配置项' :config='dataConfig' :init='formState'></SmartForm>

// jsx 修改配置
<SmartForm 配置项={自定义的配置项} config={dataConfig} init={formState}></SmartForm>

自定义基础SmartForm组件,覆写 getLabel、rules 方法,结合 vue-i18n 等国际化插件可实现组件语言的国际化。

import * as SmartAntd from 'vue-smart-antdv'
import { useI18n } from 'vue-i18n';

const i18n = useI18n()

// label 对应formItem组件接收到的label文本
// key 对应的组件类型 formType
export const getLabel = (label, key) => {
  const labelMap = {
    Input: i18n.t('InputPrefix') + label,
    Select: i18n.t('SelectPrefix') + label,
    // ...其它自定义,
  };
  return labelMap[key];
};

// params 对应config里每项formItem组件的配置 可结构取出需要的配置
export const rules = (params, extra) => {
  const { items, label, formType, ruleExtra } = params;
  const message = getLabel(label, formType);
  return [
    {
      required: true,
      message: label + REQUIRE,
    },
    ...(ruleExtra ? ruleExtra : []),
  ];
};

// template 修改配置
<SmartForm :getLabel='getLabel' :rules='rules' v-bind='props'></SmartForm>

// jsx 修改配置
<SmartForm getLabel={getLabel} rules={rules} {...props}></SmartForm>

其它配置 支持传入顶部、底部 slots

const slotsCom = {
  topSlot: () => <div style={{textAlign: 'center'}}>父组件传递 topSlot</div>,
  bottomSlot: () => <div style={{textAlign: 'center'}}>
    父组件传递 bottomSlot
    // antd-vue 提交
    <a-form-item wrapper-col={{ span: 12, offset: 6 }}>
      <a-button type="primary" htmlType="submit" html-type="submit">Submit</a-button>
    </a-form-item>
    // 或者 el
    <el-form-item wrapper-col={{ span: 12, offset: 6 }}>
      <el-button type="primary" onClick={() => {
        submitForm(formRef)
      }}>Submit</el-button>
    </el-form-item>
  </div>,
}

<SmartForm config={dataConfig} init={formState}>{slotsCom}</SmartForm>

支持ref获取组件实例

const formRef = ref();

// 如下 formRef.value.formRef 即 Form 表单实例 可以调用相关Form组件方法
const getRes = () => {
  const res = formRef.value.formRef.getFieldsValue()
}

<SmartForm ref={formRef} config={dataConfig} init={formState}></SmartForm>

config 配置参数说明 支持数组和函数形式,目前函数形式带有 {formState} 参数, 值是父组件传入的 form 表单初始值,可自主决定使用该数据作额外信息显示、绑定等操作

  config: {// 组件formItem配置
    type: Array | Function,
    default: [],
  },

主要配置参数 支持透传使用全部的 Form 组件相关属性 参数

  name: {// 组件name
    type: String,
    default: 'smartForm',
  },
  config: {// 组件formItem配置
    type: Array,
    default: [],
  },
  formProps: {// 组件 Form props
    type: Object,
    default: {},
  },
  formItemLayout: {// 组件 Form 布局
    type: Object,
    default: {
      labelCol: { span: 6 },
      wrapperCol: { span: 14 },
    },
  },
  init: {// Form 组件 双绑model的初始数据值
    type: Object,
    default: {},
  },
  isDisabledAll: {// 是否禁用整个表单
    type: Boolean,
    default: false,
  },
  noRuleAll: {// 是否关闭整个表单rule校验
    type: Boolean,
    default: false,
  },
  {
    // 除 Form.Item 表单元素外SmartForm的扩展属性
    flexRow: 1,// 每项元素是否独占一行显示
    formType: 'Select',// 对应要显示的表单组件类型(可通过 registerComp 方法定制想要对应展示的元素内容)
    noRule: false,// 是否关闭该项表单默认的 required: true, 非必填
    ruleExtra: [{ required: true, message: '',  },],// 额外的 Form.Item 校验规则 + 表单默认的 required: true, 非必填
    formRules: [{ required: true, message: '',  },],// 完全自定义编写 Form.Item 校验规则
    isFormat: () => {},// 对config里的每项配置调用传入的该格式化方法处理数据
    noLabel: false,// 不显示 label 文本
    haveDivider: false,// 是否显示 分隔线
    PropsCom: () => {},// Form.Item内使用父组件传入的方法创建
    
    // itemProps comProps 是透传 Ant-Design-Vue/Elment-plus 表单原有属性配置
    itemProps: {// Form.Item 每项组件的属性
      label: 'select',
      name: 'select',
    },
    comProps: {// Form.Item 内部表单项支持的各属性
      class: 'selectClass',
      options: [
        {
          label: 'car',
          value: 'car',
        },
        {
          label: 'phone',
          value: 'phone',
        },
      ],
    },
  },

父组件的事件统一存储放到 eventAttr 对象传递给子组件 SmartForm

const propsFn = (params) => {
  console.log(' propsFn : ', params,  )
  // 父组件相关代码操作
}

const eventAttr = {
  propsFn,
}

// jsx
<SmartForm eventAttr={eventAttr} config={dataConfig} init={formState}></SmartForm>

// vue
<SmartForm :eventAttr='eventAttr :config='dataConfig' :init='formState'></SmartForm>

可以结合服务端使用,将显示内容控制权交给后端。

const dataConfig = ref([])
const req = async () => {
  dataConfi.value = await axios.get('/formConfig')
}

onMounted(() => {
  req()
})

// jsx
<SmartForm eventAttr={eventAttr} config={dataConfig} init={formState}></SmartForm>

// vue
<SmartForm :eventAttr='eventAttr :config='dataConfig' :init='formState'></SmartForm>

其它参数详细作用请查看 packages/config 内的 defProps