前沿
关于Vue 表单中的一些小tip 在运行的时候可以很有助更快的开发,下面就一起来看看吧
1.多个表单提交 或者是 数组循环的,必须要验证
let arrForm=[]//哪些表单需要做校验 let arrModel=[]//表单的值 let newArr = [] //承接promise的返回结果 let _self=this this.makeData.forEach((item,index)=>{//将有权限的表单做校验等等 if (item.formShow) { checkForm(item.formRef)//校验 arrModel.push(item.formModel)//需要校验的表单的值 } }) function checkForm(arrName) { //根据form表单的ref,动态生成promise,再对其坐表单校验,都通过了再去做处理 var result = new Promise(function(resolve, reject) { _self.$refs[arrName][0].validate((valid) => { if (valid) { resolve(); } else { reject() } }) }) newArr.push(result) //push 得到promise的结果 } Promise.all(newArr).then(function() { //都通过了 console.log('恭喜,表单全部验证通过') }).catch(function() { console.log("err"); }); }
这样就 all 的方法就可以
2.vue 循环的 table 里共含表单验证
主要是下面的循环给验证
:prop="'tableData.' + scope.$index + '.字段名'"
例子代码:
<template> <div class="app-container"> <el-form :model="fromData" ref="from"> <el-table :data="fromData.domains"> <el-table-column label="姓名"> <template slot-scope="scope"> <el-form-item :prop="'domains.'+scope.$index+'.name'" :rules="fromaDataRules.name"> <el-input v-model="scope.row.name"></el-input> </el-form-item> </template> </el-table-column> <el-table-column label="地址"> <template slot-scope="scope"> <el-form-item :prop="'domains.'+scope.$index+'.desc'" :rules="fromaDataRules.desc"> <el-input v-model="scope.row.desc"></el-input> </el-form-item> </template> </el-table-column> </el-table> </el-form> <el-button type="warning" @click="submit('from')">submit</el-button> </div> </template> <script> export default { data() { return { fromData:{ domains:undefined }, fromaDataRules:{ name:[{ required: true, message: '请输入', trigger: 'blur' }], desc:[ { required: true, message: '请填写', trigger: 'blur' }] }, domains:[], } }, mounted(){ this.initDomains() }, methods:{ initDomains(){ this.domains=[ { name: "小林", desc: "1" }, { name: "小方", desc: "2" } ] }, init(){ this.$set(this.fromData,'domains',this.domains) }, submit(formName){ this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); } } } </script>
上述代码中关键的部分有点:
1、:prop="‘domains.'+scope.$index+'.name'" ,用于动态绑定prop到el-form-item;
2、this.$set(this.fromData,‘domains',this.domains) ,用于为fromData设置domains这个节点。
3。 model="fromData" 这个 必要封装
3. upload组件使用多个时无法绑定对应的元素
3.1 修改源码,在on-success回调中增加index索引
找到this.handleSuccess这个函数,你会发现源码中只有三个参数,
res, file,和this.uploadFiles,这与官方文档中function(response, file, fileList)参数是一致的,现在我们来看下在这里面定义一个index参数后,on-success回调中,返回的参数是什么
handleSuccess: function handleSuccess(res, rawFile) { var file = this.getFile(rawFile); if (file) { file.status = 'success'; file.response = res; this.onSuccess(res, file, this.uploadFiles); this.onChange(file, this.uploadFiles); } },
- 项目里面找到node_modules/element-ui/lib/element-ui.common.js
- 在props里面加一个要父组件传过来的参数bindIndex
onSuccess: { type: Function, default: noop }, bindIndex: null, onProgress: { type: Function, default: noop },
- 可以在上面handleSuccess这个函数中加入这个参数
this.onSuccess(res, file, this.uploadFiles, this.bindIndex);
4. 现在我们可以在el-upload中传入这个参数了
<ul>
<li v-for="(item, index) in List" :key="index">
<el-upload :bindIndex="index" :on-success="handleSuccess"></el-upload>
</li>
</ul>
- 现在我们可以来看看handleSuccess(res,)这个回调里面参数会打印出什么
handleLearnDataSuccess (res, file, fileList, index) { console.log(res, file, fileList, index) let dialog = this.dialog dialog.learningSource[index].content = { image_path: res.url, name: file.name } dialog.learningSource[index].file.push(file) },
这就是我们要拿到的index
但是有弊端 他实现的原理是修改包文件,但是方法使得其他协同工作的同事也要修改代码,才能正常运行。
3.2解决二:在调用回调时二次封装,把默认的参数和自己新增的参数作为一个新的函数返回
这里的index就是我们v-for出来的index,调用哪个upload,就把相对应的index传进去,上传成功后,我们是不是就可以把文件与index联系起来了呢
:on-success="(res,file)=>{return handleLearnDataSuccess(res,file,index)}"
当然,这里用的是es6写法,可能IE某些版本并不支持这种写法,我们可以转换一下,写成普通函数
:on-success="function (res,file) {return handleLearnDataSuccess(res,file,index)}"
4. el-select的change事件,传递多个值
在select事件 中要传递多个值 ,比如想知道下标,复原书的值
<el-table border stripe :data="searchForm.taxPlanEntityList" style=" 100%">
<el-table-column label="公司名称" align="center" min-width="140" show-overflow-tooltip>
<template slot-scope="{row,$index}" >
<el-select v-model="row.deptId" placeholder="请选择" @change="(deptId) => handleChangeDeptId(deptId, $index)">
<el-option v-for="item in projectList" :label="item.name" :value="item.deptId" :key="item.deptId"></el-option>
</el-select>
</template>
</el-table-column>
</el-table>
方法如下:
handleChangeDeptId(deptId, index) { console.log(deptId, index) // 这个就是你传过来的值了 }
后期继续更新,哈哈