关于form:orbeon-form-的日志处理

有的时候,咱们拜访 orbeon form 自带的 demo 页面时,比方 url:http://localhost:8080/orbeon/... 会遇到谬误音讯: 403 谬误: 日志文件地位: https://stackoverflow.com/que... 当您收到意外行为(例如 Form Builder 的谬误音讯或运行表单时)时,您通常能够在 Orbeon Forms 日志文件(通常称为 orbeon.log)中找到无关出错起因的更多信息。 要查看此日志:找到您的 orbeon.log 所在的地位。 开箱即用,它写在 ../logs/orbeon.log 中,绝对于您启动 servlet 容器或应用程序服务器时的当前目录。 例如,如果您从 bin 目录启动 Tomcat,则日志文件将位于 Tomcat 的日志目录中。 如果您找不到 orbeon.log,或者心愿在其余地位创立它,请在 Orbeon Forms 中编辑 WEB-INF/resouces/config/log4j.xml,找到 SingleFileAppender,而后在 \<param name= "File" value="../logs/orbeon.log"/\> 将 ../logs/orbeon.log 替换为您心愿存储 orbeon.log 的地位。 应用绝对路径,例如 /opt/tomcat/logs/orbeon.log 通常是个好主见。 一些日志片段剖析: 2021-12-18 10:18:12,169 INFO ProcessorService - Context listener - Context initialized.2021-12-18 10:18:12,192 INFO form-runner-auth - initializing2021-12-18 10:18:12,196 INFO form-runner-auth - configuring: FilterSettings(None)2021-12-18 10:18:12,200 INFO limiter - initializing这个 context listener 一看就是 Java 的货色。 ...

December 19, 2021 · 1 min · jiezi

关于form:orbeon-form-通过-url-的方式同第三方应用集成的开发明细

Form Builder 和 Form Runner 通过多种形式与其余系统集成,本文介绍 url 集成形式的实现细节。 当您应用 Form Builder 创立表单时,您能够为该表单抉择一个应用程序名称和表单名称。 例如,对于婚姻登记,您能够抉择文员作为申请名称,并抉择婚姻登记作为表格名称。 当您公布表格时,假如您在 http://www.city.gov/forms 上的服务器上部署了 Orbeon Forms,公民将可能通过拜访 http://www.city 填写新的婚姻登记,这个登记表的 url 为: http://www.city.gov/forms/fr/... 在典型的部署中,用户将从您的网站或 Web 应用程序的另一部分拜访此页面,其中蕴含指向 Orbeon Forms 提供的表单的链接。 例如,市政府可能在其网站上有一个列出公民能够填写的表格的页面,该页面链接到 http://www.city.gov/forms/fr/... 上的婚姻登记表。 Technology agnostic链接不会对您所链接的网站或应用程序所应用的技术做出任何假如。 您的站点能够应用 Drupal、WordPress、由 IIS 提供服务、应用 .NET 或任何其余技术。 例如,下图实用于以下状况:您的网站由 Microsoft IIS 提供服务,在 .NET 中实现,并且链接到由 Orbeon Forms 提供服务的表单。 Paths咱们示例中的 /fr/clerk/marriage-registration/new 是以下称为门路的内容,对于给定的表单,存在多个这样的门路。 理解这些门路是特地重要的,因为这容许您从您的网站或 Web 应用程序链接到您应用 Form Builder 创立的表单。 所有门路都与部署上下文相干,即您部署 Orbeon Forms 的地位,在咱们的示例中为 http://www.city.gov/forms。 url 标准Summary page for a given form definition: ...

December 19, 2021 · 1 min · jiezi

关于form:orbeon-form-的架构简介-如何访问用户通过-form-存储的数据

从用户的视角登程,Orbeon Forms 架构很简略。 它由 Form Builder(表单编辑器)和 Form Runner(表单运行时)组成,与数据库(长久层)对话。 此外,与用户管理系统的集成也是一种常见的场景。 您曾经应用 Form Builder 创立了表单,公布了这些表单,并设置了 Orbeon Forms,以便它将表单捕捉的数据存储在您的关系数据库中。 当初,您的另一个应用程序如何拜访这些数据? 有三种设计形式。 当用户单击表单中的提交按钮时,让 Orbeon 表单将数据发送到您的应用程序。您的应用程序为此调用 Orbeon Forms 提供的 REST API。您的应用程序间接拜访 Orbeon Forms 保留的数据库中的数据。上面逐个介绍。 办法1. Send data on submit在大多数状况下,这是最好的抉择,也是咱们举荐的抉择。 实质上,您设置 Orbeon Forms,以便当用户填写表单并提交时,Orbeon Forms 会将用户输出的数据发送到您的应用程序。 您的应用程序能够应用这些数据做任何它想做的事件,如果须要,在对 Orbeon Forms 的响应中,您的应用程序能够通知 Orbeon Forms 用户接下来应该转到哪个页面。 当用户单击在 Form Builder 中创立的表单上的提交按钮(或就此而言表单底部的任何其余按钮)时,将运行一个流程。 实质上,一个流程定义了一系列要执行的操作,其中之一能够是将数据发送到您的应用程序。 目前,流程定义在您的 properties-local.xml 中。 在您的流程中,您将应用 send() 操作来批示 Orbeon Forms 将用户输出的数据公布到您抉择的 URL。 你的应用程序能够用它接管的数据做它想做的事件:在数据库中执行一些操作,调用服务等。 如果您将 replace = "all" 参数传递给 send(),那么您的应用程序在 HTTP 响应中发送回 Orbeon Forms 的内容将被 Orbeon Forms 发送/代理回浏览器。 ...

December 19, 2021 · 1 min · jiezi

关于form:orbeon-form-的配置介绍

Orbeon Forms 通过配置属性进行配置。 它们通常设置在名为 properties-local.xml 的文件中,并存储在 Orbeon Forms WAR 文件中,如下所示:WEB-INF/resources/config/properties-local.xml: Orbeon Forms 能够做一些开箱即用的事件,而您无需在 properties-local.xml 中进行任何设置。 然而,如果您想更改默认行为(并且很可能为了设置访问控制、数据库拜访、配置按钮等),您将须要对该文件进行更改。 本文形容了该过程的基础知识。 您能够通过编辑 properties-local.xml 来更改属性。 该文件位于 Orbeon Forms Web 应用程序内的目录 WEB-INF/resources/config 中。如果该文件在您的 Orbeon Forms 装置中尚不存在,您能够通过将文件 properties-local.xml.template 重命名或复制到 properties-local.xml 中来创立它。 此时,您的 properties-local.xml 将只蕴含一个开始 \<properties\> 标记和完结 \</properties\> 标记,您须要编辑它以在这两个标记之间增加属性,如下所示: <properties xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:oxf="http://www.orbeon.com/oxf/processors"> <property as="xs:string" name="oxf.fr.persistence.provider.*.*.*" value="oracle"/></properties>属性由以下组成: 一种类型,例如 xs:boolean名称,例如 oxf.resources.versioned一个值,例如 true可选的,很少有处理器名称,例如 oxf:page-flow,它指的是 XPL 处理器名称一个例子: <property as="xs:boolean" name="oxf.resources.versioned" value="true"/>保留属性文件(例如 properties-local.xml)后,会立刻思考对大多数属性的更改,但仅在首次启动服务器时才思考对某些属性的更改。 Built-in property files这些属性的默认值在以下文件中提供,这些文件存储在 orbeon-resources-private.jar 中: config/properties-dev.xml:root of dev mode propertiesconfig/properties-prod.xml:root of prod mode propertiesconfig/properties-base.xml:base Orbeon Forms propertiesconfig/properties-xforms.xmlconfig/properties-form-runner.xmlconfig/properties-form-builder.xml通常,您不应批改这些文件。 ...

December 19, 2021 · 1 min · jiezi

关于form:Orbeon-form-的安装和使用教程

Orbeon Forms 提供了一套web表单的构建和部署计划, 实现了W3C XForms规范, 并提供一个收费的开源的社区版,以及商业版。 Orbeon Forms 曾经在世界各地的多个行业中失去利用,包含政府,银行,医疗保健,电信,和教育。 能够从 Orbeon 的 demo 页面疾速体验一下这个开源解决方案的应用: https://demo.orbeon.com/demo/... 新建一个 Form,保护 Application name 和 form name: 而后设计 form 的布局设计。比方我从 toolbox 里拖拽了一个新的 input field,能够胜利保留用户的输出值。 拜访 https://demo.orbeon.com/demo/...,查看所有用户输出的数据。 也能够下载到本地应用。下载链接: https://www.orbeon.com/download tomcat 和 orbeon form 的版本对应关系如下图所示: 从这个链接下载: https://www.orbeon.com/download 下载结束: 在 tomcat webapps 文件夹下,新建一个 orbeon 文件夹: 把下载的 orbeon.war 解压,解压之后的内容放到 orbeon 文件夹里: 启动 tomcat,拜访 url: http://localhost:8080/orbeon/... 看到 Orbeon 的启动页面: 能看到如下 demo 页面: 创立一个新的 form: ...

December 19, 2021 · 1 min · jiezi

Spring-FORM-标签库

Spring FORM标签库Spring MVC提供了一个JSP标签库(Spring Form),使将表单元素绑定到Model 数据变得更加容易。Spring Framework 提供了一些标签,用于显示 错误,设置主题和输出国际化消息。 使用Spring Form标签库的语法需要在jsp文件头部加上: <%@taglib uri="http://www.springframework.org/tags/form" prefix="form">本示例中使用的表单标签呈现HTML “form” 标签,并向内部标签公开绑定路径以进行绑定。使用绑定值呈现类型为“text”的HTML“input”标记。在HTML'span'标签中呈现字段错误。使用绑定值呈现类型为“ password”的HTML “input”标签。呈现类型为“radio”的HTML“ input”标签。呈现HTML“select”元素。支持数据绑定到所选选项。呈现单个HTML“option”。根据绑定值适当设置“selected”。呈现HTML“textarea”。呈现类型为“checkbox”的HTML“input”标签。简单注册表单示例1.修改web.xml以配置Dispatcher Servlet。web.xml <?xml version="1.0" encoding="UTF-8"?><web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>创建一个dispatcher-servlet.xml文件,其中包含所有用于处理用户请求的配置bean,它处理用户请求并将其分派到各个控制器。dispatcher-servlet.xml <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="urlMap"><map><entry key="/index.html"><ref bean="registrationController"/></entry></map></property> </bean><bean id="registrationValidator" class="registrationValidator"/><bean id="registrationController" class="RegistrationFormController"><property name="sessionForm"><value>false</value></property><property name="commandName" value="registration"></property><property name="commandClass" value="Registration"></property><property name="validator"><ref bean="registrationValidator"/></property><property name="formView"><value>index</value></property><property name="successView"><value>success</value></property></bean><bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="messages"/> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" /></beans>3.创建一个Jsp文件以从用户index.jsp接收输入,该文件包含带有Spring Form标签的所有表单字段。 index.jsp ...

October 6, 2019 · 3 min · jiezi

ElementUI嵌套Form的Dialog如何重置Form

场景第一次打开页面时,先点添加按钮选中第一行先点击添加按钮,执行resetFields(),重置form,正常。再点击修改按钮,回显用户信息,正常。 第一次打开页面时,先点修改按钮选中第一行先点击修改按钮,回显用户信息,正常。再点击添加按钮,执行resetFields(),没有重置form,异常。 分析官方文档的描述是重置为初始值。在创建form对象时,使用model绑定的表单数据对象,在form对象的mounted时期记录了下来第一次使用的表单数据对象,这个表单数据对象就是初始值,每次调用resetFields()重置表单,都是使用这个初始值,所以重置并不是清空。 <el-form ref="form" :model="form" label-width="80px">... ...</el-form>解决先调用resetFields()重置表单并移除校验结果,然后将表单数据对象置空。 resetEntityForm: function () { this.$nextTick(function () { this.$refs.entityForm.resetFields(); for (var key in this.entity) { if (this.entity.hasOwnProperty(key)) { this.entity[key] = ''; } } });}参考:解决 ElementUI form表单在dialog中重置表单,无法正确重置的问题elementui-清除弹框中表单的默认值-resetFields()element-ui 表单清空 resetFields 方法清空表单中的坑

July 11, 2019 · 1 min · jiezi

自定义表单生成器formcreate-v2介绍

介绍form-create 是一个可以通过 JSON 生成具有动态渲染、数据收集、验证和提交功能的表单生成器。并且支持生成任何 Vue 组件。结合内置17种常用表单组件和自定义组件,再复杂的表单都可以轻松搞定。 文档 | github 功能自定义组件 可生成任何Vue组件自带数据验证轻松转换为表单组件通过 JSON 生成表单通过 Maker 生成表单强大的API,可快速操作表单双向数据绑定事件扩展局部更新数据验证栅格布局内置组件17种常用表单组件对比 1.x速度更快体积更小更强大的全局配置自定义组件更容易扩展更容易支持第三方 UI 库更少的 bug示例通过 JSON 创建表单 通过 API 操作表单 @form-create包说明名称说明@form-create/iviewiview 版表单生成器@form-create/element-uielement-ui 版表单生成器@form-create/coreform-create 核心包@form-create/utilsform-create 工具包@form-create/data省市区多级联动数据使用以element-ui版本为例介绍如何在项目中使用 form-create 安装npm i @form-create/element-ui挂载全局注册 import formCreate form '@form-create/element-ui';Vue.use(formCreate);局部挂载 import formCreate form '@form-create/element-ui';export default { components:{ formCreate:formCreaet.$form() }}生成表单<template> <form-create v-model="$f" :rule="rule" @on-submit="onSubmit"></form-create></template>export default { data () { return { //表单实例对象 $f:{}, //表单生成规则 rule:[ { type:'input', field:'goods_name', title:'商品名称' }, { type:'datePicker', field:'created_at', title:'创建时间' } ] }; }, methods:{ onSubmit(formData){ //TODO 提交表单 } }};效果 ...

June 24, 2019 · 1 min · jiezi

Vue动态表单-vuedynamicform2

背景前不久,我在github上开源了一个业务工作中沉淀出来的工具 app-info-parser ,然后就有了半夜三四点回复issue邮件、修bug的爽歪歪体验,虽然上完班还要处理issue挺累的,但是也算乐在其中。 俗话说得好,开源一时爽,一直开源一直爽,所以我又来了 -。- 我所在的小组主要负责公司的公共服务搭建,组内有不下十个公共服务项目(就我一个前端,太过分了T_T),每个项目都有配套的 CURD 类的管理系统,随之而来的就是数不清的表单。 不夸张的说,我写表单都快写吐了。作为一个程序员,实在无法容忍自己把时间花在重复的事情上,所以抽时间在 element-ui 和 async-validator 的基础上写了一个动态表单组件 vue-dynamic-form 安利正式开始安装NPM 包引入,vue-dynamic-form名字被占用了(哭瞎),因此在 NPM 中使用的名字是 vue-dynamic-form2 yarn add vue-dynamic-form2# npmnpm install vue-dynamic-form2script 标签引入请自行在 github仓库 中下载对应版本的源码,引入 lib/vue-dynamic-form.umd.min.js注册全局注册 import Vue from 'Vue'import DynamicForm from 'vue-dynamic-form2'Vue.use(DynamicForm)组件内注册 <script>import DynamicForm from 'vue-dynamic-form2'export default { components: { DynamicForm }}</script>简单示例<template> <dynamic-form v-model="data" :descriptors="descriptors"> </dynamic-form></template><script>export default { data () { return { descriptors: { date: { type: 'date', label: 'date \'s label', required: false }, number: { type: 'number', label: 'number \'s label', required: true, placeholder: 'please input the number' }, string: { type: 'string', label: 'string \'s label', required: true, pattern: /^test$/g }, url: { type: 'url', label: 'url \'s label', required: true, placeholder: 'please input the url' }, email: { type: 'email', label: 'email \'s label', required: false }, enum: { type: 'enum', label: 'enum\'s label', enum: ['value-1', 'value-2'] } }, data: {} } }}</script>生成的表单 ...

June 19, 2019 · 2 min · jiezi

iview中-formtable-渲染的问题

描述需求在表格里面渲染form表单,数字保留2位小数,不足的自动补齐。 选用选用的是 iview 的组件 Form 、Input、Table。 Form表单的数据可以双向绑定,这样在对输入的数据做补零操作后,更新Form表单的model绑定的数据,即可更新。 没有使用 InputNumber 是因为它的交互用户体验不是很友好,而选用了常用的Input。但问题不是出在这里,请继续往下看。 form+tabletest.vue<template> <div> <Form ref="formTable" :model="formTable" :rules="rulesTable" inline > <Table border :columns="columns" :data="data"></Table> </Form> </div></template><script> let Trim=function(str,isGlobal) { let result; result = str.replace(/(^\s+)|(\s+$)/g,""); if(isGlobal === true) result = result.replace(/\s/g,""); return result; }; import FormItemInput from './form-item-input.vue'; export default { name:'test', components: {FormItemInput}, data() { return { //+++ form 表单 start formTable:{}, rulesTable:{}, //+++ form 表单 end // +++++++ table start data:[ { "id":1, "name":"张三", "score":"" }, { "id":2, "name":"李四", "score":"" } ], columns:[ { title: '序号', type: 'index', width: 60, align: 'center' }, { title: '姓名', key: 'name', width: 200, ellipsis:true }, { title: '成绩', key: 'score', width: 150, className:'custom-table-form', ellipsis:true, renderHeader:(h, params) => { // 2019年1月4日11:01:36 // 必填 需要展示 * return h('div', [ h('i', { style: { color: 'red', marginRight: '5px' } }, '*'), h('span', {}, params.column.title) ]); }, render:(h, params)=>{ console.log('行数据',params.index, params); /** * 2019年5月14日17:08:32 添加校验 */ let _formKey=params.column.key+'_'+params.row.id; this.rulesTable[_formKey]=[]; // 2019年6月6日11:09:32 这步会导致,数据渲染两遍 this.$set(this.$data.formTable, _formKey, params.row[params.column.key]===undefined || params.row[params.column.key]===null ? '' : params.row[params.column.key]); this.rulesTable[_formKey].push( { /** * 清掉input输入的空格,如果为空,不能通过 */ validator(rule, value, callback, source, options) { let errors = []; if (!Trim(value) ){ errors.push( new Error( "该项是必填项")); } callback(errors); }, trigger: 'blur' }, { validator(rule, value, callback, source, options) { let errors = []; // 正则控制范围,比较大小,同时存在才为true let _tmpValue= value && Number(value); // 可以出现一项:100分,或者n项 几分~几十分 let reg= /^([1-9]?[0-9]{1,2})?\0?(\.\d{1,2})?$/; if(!(reg.test(_tmpValue)&&0<=_tmpValue&&_tmpValue<=100)) { errors.push( new Error("请输入0-100之间的数字,小数点后最多允许保留2位小数") ); } callback(errors); },type:'string', trigger: 'blur' } ); return h(FormItemInput, { props:{ formTable:this.formTable, formKey:_formKey, }, on:{ 'on-form-blur':(value)=>{ // 更新提交数据 this.$refs.formTable.validateField(_formKey, (message)=>{ //2019年5月16日10:12:08 校验通过以后,保留2位小数 if(message.length==0) { this.formTable[_formKey]=Number(value).toFixed(2); console.log('formTable',this.formTable); } }); } } }); } }, ], // +++++++ table end }; }, mounted() { }, methods: {} }</script>form-item-input.vue<template> <Form-item :prop="formKey" @on-form-blur="onFormBlur" :required="required" :label="label" :setLengthNumber="setLengthNumber" :lastFormItem="lastFormItem"> <Input v-model="formTable[formKey]" ></Input> </Form-item></template><script> export default { props:{ required:{ type:Boolean, default:false }, label:{ type:String, default:'' }, formTable:Object, formKey:String, }, methods: { onFormBlur(value){ this.$emit('on-form-blur', value); } } }</script>图示 ...

June 6, 2019 · 2 min · jiezi

快速构建高性能表单JSXForm

背景表单问题,不管是在 jQuery 时代,还是 Angular/React 时代,都永远是前端工程师们的痛,但是这又是没办法的事情,业务需求多种多样,对于中后台业务而言,表单页面和报表页面基本上是中后台业务的核心展现形式,但是,React的表单真的是复杂而又难以维护。 下面我们尝试实现下面的表单: React原始代码实现export default class Example extends React.Component { constructor(){ super() this.state = { formData: { name: '', type: '' } } } render() { const { formData } = this.state return <div className="base-form-area"> <div className="form-item"> <span>名称:</span> <Input value={formData.name} onChange={event => { this.setState({ formData: { ...formData, name: event.target.value } }) }} /> </div> <div className="form-item"> <span>类型:</span> <Input value={formData.type} onChange={event => { this.setState({ formData: { ...formData, type: event.target.value } }) }} /> </div> </div> }}看着这样的代码,是否有种人生很难的苦痛,这还只是功能最简单的表单,没有校验功能,也不存在任何控制、联动逻辑,其代码量已经非常庞大了。除此之外,React原始代码实现的表单,数据和逻辑没有内敛,表单状态和数据散落在组件各个地方,导致表单复用和维护都比较困难。Antd Form实现@Form.create()export default class Editor extends React.Component { render() { const { getFieldDecorator } = this.props.form; return <div className="base-form-area"> <Form> <Form.Item label="名称"> { getFieldDecorator('name', { rules: [{required: true, message: '请输入名称'}], })( <Input /> ) } </Form.Item> <Form.Item label="类型"> { getFieldDecorator('type', { rules: [{required: true, message: '请输入类型'}], })( <Input /> ) } </Form.Item> </Form> </div> }}Antd Form语法复杂、代码量也比较庞大,说实话,到目前为止,我也没记住过它的那些方法,最严重的问题是:Antd Form存在比较严重的性能问题,当表单组件比较多的时间,页面会卡顿。JSXForm是什么JSXForm是借鉴vuejs的指令语法,在React中将表单组件的功能和逻辑进行抽象的组件,它的语法简单清晰。JSXForm的文档地址为:JSXForm ...

May 10, 2019 · 1 min · jiezi

form 表单提交前验证 onsubmit

使用form表单的onsubmit方法,在提交表单之前,对表单或者网页中的数据进行检验。onsubmit指定的方法返回true,则提交数据;返回false不提交数据。在不使用JQuery的情况下(js原生),是提交表单前拦截的较好方法。js验证form表单,示例代码:<!DOCTYPE html><html><head> <meta charset=“utf-8”> <meta name=“viewport” content=“width=device-width”> <title>form validate</title> <script src=“https://code.jquery.com/jquery-1.9.1.js"></script> <script> function validate() { // 为了方便 使用了jq获取表单元素的值,可以使用js原生获取 if ($(’#input’).val() == 1) { return true } else { alert(‘validate error!’) return false } } </script></head><body> <form action=“http://www.baidu.com” onsubmit=“return validate()"> <input type=“text” id=“input”> <input type=“submit” id=“submit” value=“提交” /> </form></body></html>

April 18, 2019 · 1 min · jiezi

让前端小姐姐愉快地开发表单

前端小姐姐:“新业务功能又有大量的表单要开发了,有没让我又高效又愉快地完成这个任务的方案呢?”哦,我想想,配置开发理念,应该比较适合,且社区也有好些这种理念的开源项目前端小姐姐:“什么叫配置开发理念呢?”就是只需要简单地定义一份JSON配置数据来开发表单前端小姐姐:“太棒了,我去search下先哈”过了一会~~前端小姐姐:“是真有不少,但我选哪个好呢?”恩,那我们就来聊聊配置理念表单开发的选型吧1. 帮助文档这是必不可少的啦,没有文档,谁敢用呢2. 直观特性展示我可不想一开始就要花大量时间去读冷冰冰的文字,然后还要发挥自己的想像力最好有超直观超形象超方便的方式展示大部分甚至全部的特性,可能是这样的:3. 开箱即用最好官方自带一整套常用的表单控件和校验规则,满足大部分常见场景,就不用去自行扩展太多了比如以下的组件就经常用到了:比如以下的校验规则就经常用到了:4. 扩展能力官方就是提供再多的组件和校验规则,也是无法满足所有的业务场景的,所以必须 友好(简单方便) 支持开发者自定义自己的表单组件和校验规则5. 支持复杂数据结构一个表单数据结构,除了简单的只有一级属性的对象类型外(如 {name: ‘daniel’, age: 18}),实际很多场景可能是这样的:{ “name”: { “firstName”: “daniel”, “lastname”: “xiao” }}可能是这样的:{ “name”: “daniel”, “hobbies”: [ { “id”: 1, “name”: “Coding” }, { “id”: 2, “name”: “Singing” } ]}一句话总结就是:支持数组类型,对象嵌套对象,对象嵌套数组,数组的项是普通类型 或 对象类型 或 数组类型6. 表单控件间交互我想说,一个表单,不是把表单控件按位置静静放在那就行了,控件之间并不独立,控件之间是有交互的这里列举下具有代表性的一些场景:“同意才能继续” 类型“城市选择器” 类型“大于18岁必填” 类型“日期比较” 类型“全名自动填写” 类型感觉已经挺多了,就不一一列举了。所以,前端小姐姐,如果候选开源项目能够满足以上所提的条件,那就可以用了前端小姐姐:“哦,那你有推荐吗?”当然。。。哈哈,接下来就是广告时间了,如果各位看官们觉得以上的选型条件合情合理,那 ncform 就是一个不错的选择了ncform,一种令人愉悦的表单开发方式,仅需配置即可生成表单UI及其交互行为。自带丰富的 标准组件 和 校验规则,开箱即用。具备强大的 控件交互 和 扩展能力,做你所想。访问官方Github了解更多呗:https://github.com/ncform/ncformtags: vue, form, json-schema, generator

March 26, 2019 · 1 min · jiezi

使用form-create动态生成vue组件,支持json格式

[github] | [说明文档]示例let rule = [ { type:‘row’, children:[ { type:‘i-col’, props:{ span:12 }, children:[ formCreate.maker.input(‘商品名称’,‘goods_name’,‘iphone’), formCreate.maker.number(‘商品加个’,‘goods_price’,8688) ] }, { type:‘i-col’, props:{ span:12 }, children:[ formCreate.maker.dateTime(‘创建时间’,‘create_at’), formCreate.maker.radio(‘是否显示’,‘is_show’).options([ {value:1,label:‘显示’}, {value:0,label:‘不显示’} ]) ] } ] }]maker.create通过建立一个虚拟 DOM的方式生成自定义组件生成Makerlet rule = [ formCreate.maker.create(‘i-button’).props({ type:‘primary’, field:‘btn’ loading:true })]$f = formCreate.create(rule);上面的代码是通过 maker 生成器动态生成一个正在加载的 iview 按钮组件Jsonlet rule = [ { type:‘i-button’, field:‘btn’ props:{ type:‘primary’, field:‘btn’, loading:true } }]$f = formCreate.create(rule);上面的代码是通过json方式动态生成一个iview 按钮组件修改可以通过一下两种方式动态修改组件的配置项通过rule修改组件生成规则rule[0].props.loading = false;通过$f.component()方法获取组件的生成规则并修改$f.component().btn.props.loading = false;maker.template通过模板的方式生成自定义组件,maker.createTmp方法是该方法的别名生成Makerlet rule = [ formCreate.maker.template(’<i-button :loading=“loading”>{{text}}<i-button>’,new Vue({ data:{ loading:true, text:‘正在加载中…’ } }))]上面的代码是通过 maker 生成器动态生成一个正在加载的 iview 按钮组件Jsonlet rule = [ { type:’template’, template:’<i-button :loading=“loading”>{{text}}<i-button>’, vm:new Vue({ data:{ loading:true, text:‘正在加载中’ } }) }]$f = formCreate.create(rule);上面的代码是通过Json方式动态生成一个iview 按钮组件修改可以通过一下两种方式动态修改vm组件内部的值通过rule获取自定义组件的vm并修改rule[0].vm.text = ‘加载完毕’;rule[0].vm.loading = false;通过$f.component()方法获取自定义组件的vm并修改$f.component().btn.vm.text = ‘加载完毕’;$f.component().btn.vm.loading = false; ...

January 18, 2019 · 1 min · jiezi

???? Ant Plus,Ant Design Form 从未如此简单

简介Ant Plus 是 Ant Design Form 的增强版,在其基础上,封装了极其简便的 Form 使用方式与 Form 相关组件的简化 API。文档https://nanxiaobei.github.io/ant-plus特点???? 极其简便:告别繁琐的 form.getFieldDecorator 样板代码与冗长的 rules 校验代码。???? 渐进增强:若不使用新的功能,完全可以把组件当作 Ant Design 中的组件来使用。⛳️ 统一提示:可全局定义 rules 校验提示信息,统一体验,告别烦乱的自定义与不可控。???? 简化 API:对 Form 相关组件的常用 API 进行了简化,一切只为更流畅的开发。安装Yarnyarn add antxnpmnpm install antx使用表单域组件的 Props 中,id 为表单域唯一标识,label 为 Form.Item 的 label。getFieldDecorator(id, options) options 参数中的项,均可直接用于组件的 Props,例如 rules、initialValue 等。Ant Plus 还对 rules 做了优化,可使用简洁的字符串,来简化校验规则的生成。完整的使用介绍,请查阅 Ant Plus Form 组件文档。import { Button } from ‘antd’;import { Form, Input } from ‘antx’;const App = ({ form }) => ( <Form api={form} data={{ username: ‘Emily’ }}> <Input label=“用户名” id=“username” rules={[‘required’, ‘string’, ‘max=10’]} max={10} msg=“full” /> <Button htmlType=“submit”>提交</Button> </Form>);export default Form.create()(App);是的,一切就是如此的简洁清晰。示例:https://codesandbox.io/s/q75nvj6vrj。对比使用 Ant Plus 与使用传统 Ant Design 搭建 Form 的代码对比。链接GitHub: https://github.com/nanxiaobei/ant-plusnpm: https://www.npmjs.com/package/antx最后欢迎尝试,欢迎 Star,体验一种从未如此简单的开发方式。 ...

January 9, 2019 · 1 min · jiezi

elementUI中form表单的upload上传图片及校验总结

自定义校验方法,因为我的项目是,分情况,可以选择是否有图,所以我定义了一个变量hasFmt,当他为false的时候,才会要求上传,走这个校验方法,rules里声明这个方法 var valiIcon = (rule, value, callback) => { // 图片验证 if (!this.hasFmt) { callback(new Error(‘请上传图片’)); } else { callback(); } icon:[ {required:true, validator: valiIcon, trigger: ‘change’ } // 图片验证 ]根据情况去切换hasFmt的值 就可以控制是否校验失败啦~~ 这就是校验图片的思路了,是不是很简单呢~~~再来说说表单带着图片一起上传fileChange(file,fileList){ this.bannerForm.filename = file.name; this.bannerForm.file = file.raw; console.log(file.raw) if(fileList.length>0){ this.hasFmt = true; }},例如,file change的时候,当fileList有值,就可以断定已经选取了图片了,讲file流保存好,(我这里是:this.bannerForm.file = file.raw;)并且可以把hasFmt变为ture啦,再者,file remover的时候 回显的时候, 等等,都要根据情况改变hasFmt的值,来达到图片的校验上传是这样的:this.$refs.bannerForm.validate((valid) => { if(valid){ let param = new FormData(); this.toBannerBtn = true; param.append(‘file’,this.bannerForm.file,this.bannerForm.filename); param.append(’tokenId’,this.$store.state.user.tokenId); param.append(’titleShort’,this.bannerForm.title_short); param.append(‘bannerType’,‘1’); param.append(’linkId’,this.bannerForm.link); param.append(‘articleId’,this.bannerForm.articleId); console.log(param) this.$post(‘bannerInfo/save’,param).then(res =>{ // console.log(res); if(res.code == 0){ this.$message({ type: ‘success’, message: res.msg }); setTimeout(() => { this.newsList(); }, 1000); this.bannerForm={}; this.bannerDialog = false; }else{ this.$message({ type: ‘warning’, message: res.msg?res.msg:‘出错了’ }); } this.toBannerBtn = false; }) } })表单校验后,就可以进行上传啦,采用的是new FormData();取值上传的,要注意 ,取消其序列号,我在公共的上传方法里封装好了,所以这里就直接调用啦小可爱们,如果觉得学到了一点点,麻烦点个赞哟,灰常感谢啦~ ...

December 28, 2018 · 1 min · jiezi

用 RxJS 实现 Redux Form

写在前面的话看这篇文章之前,你需要掌握的知识:ReactRxJS (至少需要知道 Subject 是什么)背景form 可以说是 web 开发中的最大的难题之一。跟普通的组件相比,form 具有以下几个特点:更多的用户交互。这意味着可能需要大量的自定义组件,比如 DataPicker,Upload,AutoComplete 等等。频繁的状态改变。每当用户输入一个值,都可能会对应用状态造成改变,从而需要更新表单元素或者显示错误信息。表单校验,也就是对用户输入数据的有效性进行验证。表单验证的形式也很多,比如边输入边验证,失去焦点后验证,或者在提交表单之前验证等等。异步网络通信。当用户输入和异步网络通信同时存在时,需要考虑的东西就更多了。就比如 AutoComplete,需要根据用户的输入去异步获取相应的数据,如果用户每输入一次就发起一次请求,会对资源造成很大浪费。因为每一次输入都是异步获取数据的,那么连续两次用户输入拿到的数据也有可能存在 “后发先至” 的问题。正因为以上这些特点,使 form 的开发变得困难重重。在接下来的章节中,我们会将 RxJS 和 Form 结合起来,帮助我们更好的去解决这些问题。HTML Form在实现我们自己的 Form 组件之前,让我们先来参考一下原生的 HTML Form。保存表单状态对于一个 Form 组件来说,需要保存所有表单元素的信息(如 value, validity 等),HTML Form 也不例外。那么,HTML Form 将表单状态保存在什么地方?如何才能获取表单元素信息?主要有以下几种方法:document.forms 会返回所有 <form> 表单节点。HTMLFormElement.elements 返回所有表单元素。event.target.elements 也能获取所有表单元素。document.forms[0].elements[0].value; // 获取第一个 form 中第一个表单元素的值const form = document.querySelector(“form”);form.elements[0].value; form.addEventListener(‘submit’, function(event) { console.log(event.target.elements[0].value);});Validation表单校验的类型一般分为两种:内置表单校验。默认会在提交表单的时候自动触发。通过设置 novalidate 属性可以关闭浏览器的自动校验。JavaScript 校验。<form novalidate> <input name=‘username’ required/> <input name=‘password’ type=‘password’ required minlength=“6” maxlength=“6”/> <input name=‘email’ type=‘email’/> <input type=‘submit’ value=‘submit’/></form>存在的问题定制化很难。 比如不支持 Inline Validation,只有 submit 时才能校验表单,且 error message 的样式不能自定义。难以应对复杂场景。 比如表单元素的嵌套等。Input 组件的行为不统一,从而难以获取表单元素的值。 比如 checkbox 和 multiple select,取值的时候不能直接取 value,还需要额外的转换。var $form = document.querySelector(‘form’);function getFormValues(form) { var values = {}; var elements = form.elements; // elemtns is an array-like object for (var i = 0; i < elements.length; i++) { var input = elements[i]; if (input.name) { switch (input.type.toLowerCase()) { case ‘checkbox’: if (input.checked) { values[input.name] = input.checked; } break; case ‘select-multiple’: values[input.name] = values[input.name] || []; for (var j = 0; j < input.length; j++) { if (input[j].selected) { values[input.name].push(input[j].value); } } break; default: values[input.name] = input.value; break; } } } return values;}$form.addEventListener(‘submit’, function(event) { event.preventDefault(); getFormValues(event.target); console.log(event.target.elements); console.log(getFormValues(event.target));});React Rx Form感兴趣的同学可以先去看一下源码 https://github.com/reeli/reac...React 与 RxJSRxJS 是一个非常强大的数据管理工具,但它并不具备用户界面渲染的功能,而 React 却特别擅长处理界面。那何不将它们的长处结合起来?用 React 和 RxJS 来解决我们的 Form 难题。既然知道了它们各自的长处,所以分工也就比较明确了: RxJS 负责管理状态,React 负责渲染界面。设计思路与 Redux Form 不同的是,我们不会将 form 的状态存储在 store 中,而是直接保存在 <Form/> 组件中。然后利用 RxJS 将数据通知给每一个 <Field/> ,然后 <Field/> 组件会根据数据去决定自己是否需要更新 UI,需要更新则调用 setState ,否则什么也不做。举个例子,假设在一个 Form 中有三个 Field (如下),当只有 FieldA 的 value 发生变化时, 为了不让 <Form/> 和其子组件也 re-render,Redux Form 内部需要通过 shouldComponentUpdate() 去限制。// 伪代码<Form> <FieldA/> <FieldB/> <FieldC/></Form>而 RxJS 能把组件更新的粒度控制到最小,换句话说,就是让真正需要 re-render 的 <Field/> re-render,而不需要 re-render 的组件不重新渲染 。核心是 Subject从上面的设计思路可以总结出以下两个问题:Form 和 Field 是一对多的关系,form 的状态需要通知给多个 Field。Field 需要根据数据去修改组件的状态。第一个问题,需要的是一个 Observable 的功能,而且是能够支持多播的 Observable。第二个问题需要的是一个 Observer 的功能。在 RxJS 中,既是 Observable 又是 Observer,而且还能实现多播的,不就是 Subject 么!因此,在实现 Form 时,会大量用到 Subject。formState 数据结构Form 组件中也需要一个 State,用来保存所有 Field 的状态,这个 State 就是 formState。那么 formState 的结构应该如何定义呢?在最早的版本中,formState 的结构是长下面这个样子的:interface IFormState { [fieldName: string]: { dirty?: boolean; touched?: boolean; visited?: boolean; error?: TError; value: string; };}formState 是一个对象,它以 fieldName 为 key,以一个 保存了 Field 状态的对象作为它的 value。看起来没毛病对吧?但是。。。。。最后 formState 的结构却变成了下面这样:interface IFormState { fields: { [fieldName: string]: { dirty?: boolean; touched?: boolean; visited?: boolean; error?: string | undefined; }; }; values: { [fieldName: string]: any; };}Note: fields 中不包含 filed value,只有 field 的一些状态信息。values 中只有 field values。为什么呢???其实在实现最基本的 Form 和 Field 组件时,以上两种数据结构都可行。那问题到底出在哪儿?这里先买个关子,目前你只需要知道 formState 的数据结构长什么样就可以了。数据流为了更好的理解数据流,让我们来看一个简单的例子。我们有一个 Form 组件,它的内部包含了一个 Field 组件,在 Field 组件内部又包含了一个 Text Input。数据流可能是像下面这样的:用户在输入框中输入一个字符。Input 的 onChange 事件会被 Trigger。Field 的 onChange Action 会被 Dispatch。根据 Field 的 onChange Action 对 formState 进行修改。Form State 更新之后会通知 Field 的观察者。Field 的观察者将当前 Field 的 State pick 出来,如果发现有更新则 setState ,如果没有更新则什么都不做。setState 会使 Field rerender ,新的 Field Value 就可以通知给 Input 了。核心组件首先,我们需要创建两个基本组件,一个 Field 组件,一个 Form 组件。Field 组件Field 组件是连接 Form 组件和表单元素的中间层。它的作用是让 Input 组件的职责更单一。有了它之后,Input 只需要做显示就可以了,不需要再关心其他复杂逻辑(validate/normalize等)。况且,对于 Input 组件来说,不仅可以用在 Form 组件中,也可以用在 Form 组件之外的地方(有些地方可能并不需要 validate 等逻辑),所以 Field 这一层的抽象还是非常重要的。拦截和转换。 format/parse/normalize。表单校验。 参考 HTML Form 的表单校验,我们可以把 validation 放在 Field 组件上,通过组合验证规则来适应不同的需求。触发 field 状态的 改变(如 touched,visited)给子组件提供所需信息。 向下提供 Field 的状态 (error, touched, visited…),以及用于表单元素绑定事件的回调函数 (onChange,onBlur…)。利用 RxJS 的特性来控制 Field 组件的更新,减少不必要的 rerender。 与 Form 进行通信。 当 Field 状态发生变化时,需要通知 Form。在 Form 中改变了某个 Field 的状态,也需要通知给 Field。Form 组件管理表单状态。 Form 组件将表单状态提供给 Field,当 Field 发生变化时通知 Form。提供 formValues。在表单校验失败的时候,阻止表单的提交。通知 Field 每一次 Form State 的变化。 在 Form 中会创建一个 formSubject&dollar;,每一次 Form State 的变化都会向 formSubject&dollar; 上发送一个数据,每一个 Field 都会注册成为 formSubject&dollar; 的观察者。也就是说 Field 知道 Form State 的每一次变化,因此可以决定在适当的时候进行更新。当 FormAction 发生变化时,通知给 Field。 比如 startSubmit 的时候。组件之间的通信Form 和 Field 通信。Context 主要用于跨级组件通信。在实际开发中,Form 和 Field 之间可能会跨级,因此我们需要用 Context 来保证 Form 和 Field 的通信。Form 通过 context 将其 instance 方法和 formState 提供给 Field。Field 和 Form 通信。Form 组件会向 Field 组件提供一个 d__ispatch__ 方法,用于 Field 和 Form 进行通信。所有 Field 的状态和值都由 Form 统一管理。如果期望更新某个 Field 的状态或值,必须 dispatch 相应的 action。表单元素和 Field 通信表单元素和 Field 通信主要是通过回调函数。Field 会向表单元素提供 onChange,onBlur 等回调函数。接口的设计对于接口的设计来说,简单清晰是很重要的。所以 Field 只保留了必要的属性,没有将表单元素需要的其他属性通过 Field 透传下去,而是交给表单元素自己去定义。通过 Child Render,将对应的状态和方法提供给子组件,结构和层级更加清晰了。Field:type TValidator = (value: string | boolean) => string | undefined;interface IFieldProps { children: (props: IFieldInnerProps)=> React.ReactNode; name: string; defaultValue?: any; validate?: TValidator | TValidator[];}Form:interface IRxFormProps { children: (props: IRxFormInnerProps) => React.ReactNode; initialValues?: { [fieldName: string]: any; }}到这里,一个最最基本的 Form 就完成了。接下来我们会在它的基础上进行一些扩展,以满足更多复杂的业务场景。EnhanceFieldArrayFieldArray 主要用于渲染多组 Fields。回到我们之前的那个问题,为什么要把 formState 的结构分为 fileds 和 values?其实问题就出在 FieldArray,初始长度由 initLength 或者 formValues 决定。formState 整体更新。FormValues通过 RxJS,我们将 Field 更新的粒度控制到了最小,也就是说如果一个 Field 的 Value 发生变化,不会导致 Form 组件和其他 Feild 组件 rerender。既然 Field 只能感知自己的 value 变化,那么问题就来了,如何实现 Field 之间的联动?于是 FormValues 组件就应运而生了。每当 formValues 发生变化,FormValues 组件会就把新的 formValues 通知给子组件。也就是说如果你使用了 FormValues 组件,那么每一次 formValues 的变化都会导致 FormValues 组件以及它的子组件 rerender,因此不建议大范围使用,否则可能带来性能问题。总之,在使用 FormValues 的时候,最好把它放到一个影响范围最小的地方。也就是说,当 formValues 发生变化时,让尽可能少的组件 rerender。在下面的代码中,FieldB 的显示与否需要根据 FieldA 的 value 来判断,那么你只需要将 FormValues 作用于 FIeldA 和 FieldB 就可以了。<FormValues> {({ formValues, updateFormValues }) => ( <> <FieldA name=“A” /> {!!formValues.A && <FieldB name=“B” />} </> )}</FormValues>FormSectionFormSection 主要是用于将一组 Fields group 起来,以便在复用在多个 form 中复用。主要是通过给 name添加前缀来实现的。那么怎样给 Field 和 FieldArray 的 name 添加前缀呢?我首先想到的是通过 React.Children 拿到子组件的 name,再和 FormSection 的 name 拼接起来。但是,FormSection 和 Field 有可能不是父子关系!因为 Field 组件还可以被抽成一个独立的组件。因此,存在跨级组件通信的问题。没错!跨级组件通信我们还是会用到 context。不过这里我们需要先从 FormConsumer 中拿到对应的 context value,再通过 Provider 将 prefix 提供给 Consumer。这时 Field/FieldArray 通过 Consumer 拿到的就是 FormSection 中的 Provider 提供的值,而不再是由 Form 组件的 Provider 所提供。因为 Consumer 会消费离自己最近的那个 Provider 提供的值。<FormConsumer> {(formContextValue) => { return ( <FormProvider value={{ …formContextValue, fieldPrefix: ${formContextValue.fieldPrefix || ""}${name}., }} > {children} </FormProvider> ); }}</FormConsumer>测试Unit Test主要用于工具类方法。Integration Test主要用于 Field,FieldArray 等组件。因为它们不能脱离 Form 独立存在,所以无法对其使用单元测试。Note: 在测试中,无法直接修改 instance 上的某一个属性,以为 React 将 props 上面的节点都设置成了 readonly (通过 Object.defineProperty 方法)。 但是可以通过整体设置 props 绕过。instance.props = { …instance.props, subscribeFormAction: mockSubscribeFormAction, dispatch: mockDispatch,};Auto Fill Form Util如果项目中的表单过多,那么对于 QA 测试来说无疑是一个负担。这个时候我们希望能够有一个自动填表单的工具,来帮助我们提高测试的效率。在写这个工具的时候,我们需要模拟 Input 事件。input.value = ‘v’;const event = new Event(‘input’, {bubbles: true});input.dispatchEvent(event);我们的期望是,通过上面的代码去模拟 DOM 的 input 事件,然后触发 React 的 onChange 事件。但是 React 的 onChange 事件却没有被触发。因此无法给 input 元素设置 value。因为 ReactDOM 在模拟 onChange 事件的时候有一个逻辑:只有当 input 的 value 改变,ReactDOM 才会产生 onChange 事件。React 16+ 会覆写 input value setter,具体可以参考 ReactDOM 的 inputValueTracking。因此我们只需要拿到原始的 value setter,call 调用就行了。const nativeInputValueSetter = Object.getOwnPropertyDescriptor(window.HTMLInputElement.prototype, “value”).set;nativeInputValueSetter.call(input, “v”);const event = new Event(“input”, { bubbles: true});input.dispatchEvent(event);Debug打印 Log在 Dev 环境中,可以通过 Log 来进行 Debug。目前在 Dev 环境下会自动打印 Log,其他环境则不会打印 Log。Log 的信息主要包括: prevState, action, nextState。Note: 由于 prevState, action, nextState 都是 Object,所以别忘了在打印的时候调用 cloneDeep,否则无法保证最后打印出来的值的正确性,也就是说最后得到的结果可能不是打印的那一时刻的值。最后这篇文章只讲了关于 React Rx Form 的思路以及一些核心技术,大家也可以按照这个思路自己去实现一版。当然,也可以参考一下源码,欢迎来提建议和 issue。Github 地址: https://github.com/reeli/reac… ...

December 28, 2018 · 4 min · jiezi

Vue动态生成表单组件(vue-generate-form)

简介Vue动态生成表单组件 可以根据数据配置表单 使用的UI库是iView 整体组件布局方式借鉴了form-create的写法 在此表示感谢在Vue里 一般要用到什么组件或数据 都得提前声明所以要根据数据来生成表单 只能使用Vue的render函数要做这一个组件 其实并不难 看一下Vue官方示例 再找个UI组件库 差不多就能写出来如果对项目有兴趣 可以fork或克隆项目 自行研究 有问题或BUG欢迎提issues文档在线DEMO表单组件Input 输入框Button 按钮Radio 单选框Checkbox 多选框Icon 图标Switch 开关Select 选择器Slider 滑块DatePicker 日期选择器TimePicker 时间选择器Cascader 级联选择器InputNumber 数字输入框Rate 评分Upload 上传ColorPicker 颜色选择器使用在单文件组件中引用npm i vue-generate-formimport iView from ‘iview’import VueGenerateForm from ‘vue-generate-form’import ‘iview/dist/styles/iview.css’Vue.use(iView)Vue.use(VueGenerateForm)<template> <div id=“app”> <VueGenerateForm :options=“options”/> // 或者 <vue-generate-form :options=“options”/> </div></template>在HTML文件中直接引用使用的是dist目录中的vue-generate-form.js<link rel=“stylesheet” type=“text/css” href=“iview.css”><div id=“app”> <vue-generate-form :options=“options”/></div><script src=“vue.js”></script><script src=“iview.js”></script><script src=“vue-generate-form.js”></script>

December 25, 2018 · 1 min · jiezi