21.Vue技术栈开发实战-Form表单
服务器端增加了一条路由叫做formData。待会我们用到的时候,会把表单提交到这个url下。并把提交的内容打印一下。
提前创建好的form页面。
首先来看下iview的表单组件,
它的最外层是一个Form组件,不是用的原生表单的提交方式,需要把提交的数据获取到,通过ajax去提交的。
里面没一条都用FormItem来包裹
动态增减表单项
新增一个表单元素。
这个示例里面,没有真正的去调接口,也没有真正的把添加的这些项添加到一个数据里作为一个提交,我们待会去真正的创建一个动态表单,表单通过后端返回来,我们这个表单里面需要有哪些项,验证规则等通通都是通过后端去获取,最后会提交并验证,
前端使用表单
给这个div加个padding,显得好看一点
api内定义请求,提交表单
添加一个提交按钮
服务端返回success
这里先注销掉
token的时间设置为一天
,
来登陆一下,lison 123
url楼了一个data
服务端的输出
表单的验证
给form组件定义rules属性
规则可以从官方的代码中复制过来
trigger是什么时候触发这个验证
还要给formItem设置prop属性
前面带小红星 就是必填的
失去焦点时候的提示信息。但是也是提交成功了。因为我们没有做判断
在点击的时候,需要调用form表单的方法,要调用这个方法,就需要获取到这个form
下面是官方的代码
如果valid是true就尅向后端提交了。
还需要给form表单绑定一个model属性,把form表单的对象传进去。
有验证就提交不了
验证规则都过了才正常的提交
自定义验证
复制官方的示例
它是一个函数,里面有三个参数。最后一定要调用callback(),否则最后是不会执行的,value如果为空字符串。那么就会提示一个错误,这里和required设置为true是一样的
判断如果用户名不是lison就报错
改个名字叫做validateName,然后在blur的时候触发,
随便输入个name就报错
不填写的提示
动态表单
实际开发过程中,你的表单不可能是这样一个个的写出来的
我们经常会通过一个系统,里面通过拖拽等方式生成一个表单页 ,这个表单页,最后把数据存储起来
这样表单就不能写死了,通过数据去生成渲染表单页,验证规则都要在数据里面存着,
先说动态组件
要封装一个组件,只要传给他一个数据,就能把数据渲染成表单。
引入这个组件,注册并使用这个组件,传入的formList一般是在后端去获取的。
这里我们为了演示,直接在这里定义。
封装组件
循环这个list,所有的表单项,应该都包裹在FormItem里面。
需要给它一个key,一个页面里面不止一个form表单。用一个唯一标识这个form组件的
这里用this._uid每一个组件的uid都是不同的,
用uid 拼接上当前的索引,
label
最简单的方式是,在之类判断item.type是不是text类型,那么就显示一个Input
把labelWidth作为一个属性传进来,默认是100,同时设置label在文本框的左边。
用动态组件
动态组件是vue的一个内置组件,它就叫做component
有一个必须的属性是is。用来标识组件是哪个组件,比如一个input标签。那么绑定的值就是input。拿到这个input后,它就会给你渲染一个component,渲染成一个input标签。
这里我们要渲染的是iview的i-input标签。
组件内应is接受这个type
这样就渲染出来了
范围从10到40
如果想设置它的范围的话就要设置为range的属性
作为v-model绑定一个范围
这样就是一个范围的区间了。初始左边是10,右边是40
select里面有嵌套的组件
就需要有 一个用来标识子级的属性
这样渲染了一个下拉菜单。
里面再嵌套一个component,然后循环children去渲染。
key值拼接上当前的i
这里应该渲染的是child里面的list
报一个错误
如果没有这个children就不应该渲染这个list。
外层用template嵌套一层,判断是否包含children的属性
改成option也不管用
这里应该是item.children.type
option组件必须有个value
现在就没问题了
radio
还有一个有子集的元素就是checkbox、radio。
目前是多选,怎么设置单选呢?需要给它绑定一个label
绑定label的属性
现在就是单选了
checkbox
多选框的value是个数组
switch
其他的组件自己根据需求再去加
验证
不同的表单验证规则是不一样的。
给姓名这个字段,加上rule
组件内就需要传入model是填入的数据,rules是规则对象。
如果表单的数据在一开始就传进来的话,我们就需要在mounted里面做处理。
如果list做了变化,还需要监听list的变化。watch监听list的变化。
初始化传进来,所有对象的value。它的初始值是多少,方便我们做重置操作。
如果用form表单内置的方法。是无效的,因为数据是传进来的,它没法改父组件的这些数据。
而且我们的数据是这样定义的,而不是一个对象,对象里面是每一个value
所以这里我们要自己去实现重置的操作。用map遍历每一个对象的value,它返回的是一个数组。
在data里面定义这个initValueList数组,
map遍历对象 错了应该改成list
遍历里面做操作,把当前表单对象里面的rules写在rules对象上。
rules的数组,valueList的数组,分别赋值。
定义rules和valueList
然后把valueList传给这个model
formItem上必须设置一个属性prop。就是当前值的字段名
这样你的验证才会生效
一刷新页面,验证就触发了
写上数据后,验证没有消失。
用v-if验证这个对象有值,也就是length不为0才去渲染。
现在就正常显示了
光标放上去,离开后触发验证。
输入值,鼠标离开,还是不行。出现这个问题的原因可能是这个值压根没有填进去。
验证绑定的值是,我们内部处理成的 valueList
所以这里要做一个替换,外部的列表传进来之后,我们最后提交表单,都跟外部的列表没有多大关系了。提交的其实是valueList
所以这里我们绑定valueList,这里改成valueList[属性是item.name]
输入值光标离开,验证通过。
提交
把提交按钮直接做到里面。
提交按钮是和这为蓝色,type="primary" ,
分别绑定上事件
重置的时候,先把list深拷贝一份。先引入clonedeep
上面方法改成initValueList数组的形式,然后下面做深拷贝。返回给valueList
重置后的效果
提交
提交要调用一个接口,提交的数据就是valueList,因为我们在表单上修改的都是他的值,
提交的时候需要先调用form表单的Validate来验证一下表单的规则。给这个表单加ref属性就可以获取到表单的实例
如果返回的为true就可以调用接口啦。
接口我们在内部去引入。剪切到组件内部。
调用方法,第一个参数是url,我们可以作为属性传进来。
String类型,且是必须的
then里面触发结果,把这个结果抛出去。
出错的情况
这里加一个参数url
调用表单组件的时候传入url
定义url
后端的输出
有些验证是在服务端做的。node服务端判断 输入的用户名是否是lison,如果不是就返回 姓名不对。
error.response才能拿到后端返回的错误。
error.response.data就是我们服务端返回的数据了。
可以在axios里面拦截请求
这里还是改成error
出现了错误,让文本框下出现错误提示
formItem有一个error属性,如果传入一个字符串,就会显示这个字符串的错误信息。
我们应该有一个对象专门来控制错误信息。
在这里也遍历一下
出现错误遍历这个错误。复制到errorStore对象上。
填入a,点击提交按钮后的提示。
换一个再提交就不提示了
给这个最外层的component绑定原生的focus事件。组件的最外层html元素绑定原生focus事件。
必须要加native。如果不加的话有的组件是没有这个focus事件的
传入item.name
每次获取焦点了就把这个errorStore清空。
没效果
看下这个事件有没有被触发
光标获取,没有触发
把事件绑定到formItem上
前面加@click
修改一个值,还是可以的
提交表单
服务端获取到的数据。
点击重置就都重置了。
以上就是我们动态表单的一种实现方式。通过给的列表传进去,就会渲染出对应的表单。
动态组件,我们后面还会讲到
本节代码
结束