单个校验 核心为 validateField() 而非validate()
<el-form
:inline="false"
:rules="rules"
:model="formInline"
ref="formInline"
class="demo-form-inline"
label-width="185px"
>
<el-form-item label="协管协议:" prop="escrowFiles" inline-message="true">
// 此处↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
<FileUploadIndexS :types="['pdf']" @escrowFilesEmit="(val) => {escrowFilesEmit(val,'escrowFiles')}" />
</el-form-item>
<el-form-item label="协管协议照片:" prop="escrowImgs">
<FileUploadIndexS :types="['png', 'jpg', 'jpeg']" />
</el-form-item>
<el-form-item label="资产移交手续:" prop="assetFiles">
<FileUploadIndexS :types="['pdf']" @assetImgsEmit="assetImgsEmit" />
</el-form-item>
<el-form-item label="资产移交手续照片:" prop="assetImgs">
<FileUploadIndexS :types="['png', 'jpg', 'jpeg']" />
</el-form-item>
</el-form>
/* 协议文件 */
escrowFilesEmit({ url,name },prop){
this.formInline.escrowFiles = [...this.formInline.escrowFiles,{filesUr:url,filesName:name}]
this.$refs.formInline.validateField(prop,val => !val ? true : false);
},
完整代码
父组件
<!--
* @Author : qixiao
* @Date : 2023-06-28 22:03:07
* @LastEditors : qixiao
* @LastEditTime : 2023-07-03 12:07:51
* @FilePath : \第三方\Sanfang-project\src\views\thirdunit\project\protect.vue
* @Description :
*
-->
<template>
<div class="pages">
<!-- 1.项目详情 -->
<p class="detail_tit">项目详情</p>
<!-- 1.1 详细描述 -->
<el-descriptions
title=""
:column="4"
border
class="margin-top centers"
direction="vertical"
>
<el-descriptions-item label="管护主体">{{
detailList.supervisorName
}}</el-descriptions-item>
<el-descriptions-item label="负责人">{{
detailList.contacts
}}</el-descriptions-item>
<el-descriptions-item label="项目地址">{{
detailList.county + detailList.town + detailList.village
}}</el-descriptions-item>
<el-descriptions-item label="联系电话">{{
detailList.contactsPhone
}}</el-descriptions-item>
</el-descriptions>
<!-- 2.合同及供应商信息 -->
<p class="detail_tit bottoms">合同及供应商信息</p>
<el-form
:inline="false"
:rules="rules"
:model="formInline"
ref="formInline"
class="demo-form-inline"
label-width="185px"
>
<el-form-item label="协管协议:" prop="escrowFiles" inline-message="true">
<FileUploadIndexS :types="['pdf']" @escrowFilesEmit="(val) => {escrowFilesEmit(val,'escrowFiles')}" />
</el-form-item>
<el-form-item label="协管协议照片:" prop="escrowImgs">
<FileUploadIndexS :types="['png', 'jpg', 'jpeg']" />
</el-form-item>
<el-form-item label="资产移交手续:" prop="assetFiles">
<FileUploadIndexS :types="['pdf']" @assetImgsEmit="assetImgsEmit" />
</el-form-item>
<el-form-item label="资产移交手续照片:" prop="assetImgs">
<FileUploadIndexS :types="['png', 'jpg', 'jpeg']" />
</el-form-item>
</el-form>
<!-- 3.保存 -->
<div class="fotter">
<el-button type="primary" @click="Ctrl_S('formInline')">保 存</el-button>
<el-button type="info">取 消</el-button>
</div>
</div>
</template>
<script>
import FileUploadIndexS from "@/views/components/construction/FileUploadIndexS.vue";
export default {
components: { FileUploadIndexS },
props: [],
data() {
/* 托管协议文件 */
var escrowFilesRules = (rule, value, callback, source) => {
if (this.formInline.escrowFiles.length == 0) {
callback(new Error("托管协议文件不能为空"));
} else {
callback();
}
};
/* 协管协议照片 */
var escrowImgsRules = (rule, value, callback, source) => {
if (this.formInline.escrowImgs.length == 0) {
callback(new Error("协管协议照片为空"));
} else {
callback();
}
};
/* 资产移交手续 */
var assetFilesRules = (rule, value, callback, source) => {
if (this.formInline.assetFiles.length == 0) {
callback(new Error("资产移交手续不能为空"));
} else {
callback();
}
};
/* 资产移交手续照片 */
var assetImgsRules = (rule, value, callback, source) => {
if (this.formInline.assetImgs.length == 0) {
callback(new Error("资产移交手续照片不能为空"));
} else {
callback();
}
};
return {
/* 描述列表 */
detailList: {},
/* route传参 */
routeDate: this.$route.query.id,
/* form */
formInline: {
escrowFiles: [],
escrowImgs: [],
assetFiles: [],
assetImgs: [],
},
rules: {
escrowFiles: [
{
required: true,
message: "协管协议不能为空",
trigger: "change",
validator: escrowFilesRules,
},
],
escrowImgs: [
{
required: true,
message: "协管协议照片不能为空",
trigger: "change",
validator: escrowImgsRules,
},
],
assetFiles: [
{
required: true,
message: "资产移交手续",
trigger: "change",
validator: assetFilesRules,
},
],
assetImgs: [
{
required: true,
message: "资产移交手续照片",
trigger: "change",
validator: assetImgsRules,
},
],
},
};
},
mounted() {},
created() {},
methods: {
/* 保存 */
Ctrl_S(formName){
this.$refs[formName].validate((valid) => {
if (valid) {
alert('submit!');
} else {
console.log('error submit!!');
return false;
}
});
},
/* 协议文件 */
escrowFilesEmit({ url,name },prop){
this.formInline.escrowFiles = [...this.formInline.escrowFiles,{filesUr:url,filesName:name}]
this.$refs.formInline.validateField(prop,val => !val ? true : false);
},
/* 手续文件 */
assetImgsEmit({url,name},prop){
this.formInline.assetFiles = [...this.formInline.assetFiles,{filesUr:url,filesName:name}]
this.$refs.formInline.validateField(prop,val => !val ? true : false);
},
/* 手续文件 */
assetImgsEmit({url,name}){
this.formInline.assetFiles = [...this.formInline.assetFiles,{filesUr:url,filesName:name}]
this.$refs.formInline.validate();
},
/* 手续文件 */
assetImgsEmit({url,name}){
this.formInline.assetFiles = [...this.formInline.assetFiles,{filesUr:url,filesName:name}]
this.$refs.formInline.validate();
},
},
};
</script>
<style lang='scss' scoped>
.pages {
::v-deep
.centers
.el-descriptions__body
.el-descriptions__table
.el-descriptions-item__label {
text-align: center !important;
}
::v-deep
.centers
.el-descriptions__body
.el-descriptions__table
.el-descriptions-item__content {
text-align: center !important;
}
.bottoms {
margin-top: 20px;
}
.fotter {
margin-top: 20px;
width: 100%;
height: 40px;
text-align: center;
}
::v-deep .el-form-item__error{
/* form校验样式 */
// left:185px;
}
}
</style>
子组件(文件、图片上传组件)
src\views\components\construction\FileUploadIndexS.vue
<!--
* @Author : qixiao
* @Date : 2023-06-29 09:50:43
* @LastEditors: liushumin
* @LastEditTime: 2023-06-29 22:17:04
* @FilePath : \第三方\Sanfang-project\src\views\components\construction\FileUploadIndexS.vue
* @Description :
*
-->
<template>
<div class="upload-file">
<el-upload
:action="uploadFileUrl"
:limit="limit"
:list-type="types.includes('pdf') ? 'none' : 'picture-card'"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:file-list="fileList"
:http-request="myUpload"
:before-upload="handleBeforeUpload"
>
<i v-if="!types.includes('pdf') ? (!text ? true :false) : false" class="el-icon-plus"></i>
<el-button
v-if="
types.includes('pdf')
? limit == fileList.length
? false
: true
: false
"
>点击上传</el-button
>
<span v-if="text ? (limit == fileList.length ? false : true) : false"
>上传</span
>
</el-upload>
<el-dialog
title="图片预览"
:append-to-body="true"
:visible.sync="dialogVisible"
>
<img
style="max-height: 70vh; max-width: 100%"
:src="dialogImageUrl"
alt=""
/>
</el-dialog>
</div>
</template>
<script>
export default {
components: {},
props: ["limit", "types", "text"],
data() {
return {
dialogImageUrl: "", //预览
dialogVisible: false, //预览
uploadFileUrl: process.env.VUE_APP_BASE_API + "/nt/common/file/upload", // 上传文件服务器地址
fileList: [],
// ["png", "jpg", "jpeg","pdf"]
fileType: this.types, //文件格式
fileSize: 60, //文件大小
};
},
watch:{
"fileList"(J,K){
if(J.length == this.limit) {
let dom = document.querySelector(".el-upload");
dom.style.setProperty("display","block")
}
}
},
mounted() {},
created() {},
methods: {
handleRemove(file, fileList) {
console.log(file);
console.log(fileList);
let arr = [];
this.fileList = [];
fileList.map((item) => arr.push(item.url));
fileList.map((item) => this.fileList.push({ url: item.url }));
console.log(arr);
this.$emit("remove", arr);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
if (!file.url.includes(".pdf")) {
this.dialogVisible = true;
} else {
window.open(file.url);
}
},
myUpload(content) {
console.log(content);
let param = new FormData(); // 创建form对象
param.append("uploadfile", content.file, content.file.name);
param.append("source", "gb"); // 高标
const loading = this.$loading({
lock: true,
text: "上传中,请稍等",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
console.log(param);
this.axios({
url: content.action,
method: "post",
headers: {
Authorization: window.localStorage.getItem("TokenKey") || "",
},
data: param,
}).then((response) => {
if (response.data.code == 200) {
console.log(response.data.data);
loading.close();
content.onSuccess(response.data.data);
this.$nextTick(() => {
this.fileList.push({
url: response.data.data.result.url,
name: response.data.data.result.originalFilename,
});
});
console.log(response.data.data.result.url);
console.log(this.limit, this.fileList.length);
if (response.data.data.result.url.includes(".pdf")) {
this.$emit("pdfEmit", {
url: response.data.data.result.url,
name: response.data.data.result.originalFilename,
});
/* 协管协议: */
this.$emit("escrowFilesEmit", {
url: response.data.data.result.url,
name: response.data.data.result.originalFilename,
});
/* 资产移交手续: */
this.$emit("assetImgsEmit", {
url: response.data.data.result.url,
name: response.data.data.result.originalFilename,
});
} else {
this.$emit("imgUrl", response.data.data.result.url);
/* 协管协议照片 */
this.$emit("escrowImgsEmit", response.data.data.result.url);
/* 资产移交手续照片 */
this.$emit("assetImgsEmit", response.data.data.result.url);
}
}
console.log(this.fileList);
});
},
// 上传前校检格式和大小
handleBeforeUpload(multipartFile) {
// 校检文件类型
if (this.fileType) {
const fileName = multipartFile.name.split(".");
const fileExt = fileName[fileName.length - 1];
const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
if (!isTypeOk) {
this.$modal.msgError(
`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`
);
return false;
}
}
// 校检文件大小
if (this.fileSize) {
const isLt = multipartFile.size / 1024 / 1024 < this.fileSize;
if (!isLt) {
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
return false;
}
}
this.$modal.loading("正在上传文件,请稍候...");
this.number++;
return true;
},
},
};
</script>
<style lang="scss" scoped>
::v-deep .el-dialog__body {
padding: 20px 20px 30px 20px !important;
text-align: center;
}
::v-deep .el-upload-list__item.is-success:focus:not(:hover) {
display: none !important;
}
</style>