睢宁做网站,网页制作工具分哪两类,wap 在线,华泰保险公司官方网站1.引入
本次框架是Ruoyi-plusvue2element组合。
2.样式
由于是后台项目#xff0c;样式要求统一#xff0c;不可以有的输入框长有的短。着重几点#xff1a;
1.关于form表单应该如何水平布局
在element中#xff0c;form有个属性叫#xff1a;:inlinetruevue2element组合。
2.样式
由于是后台项目样式要求统一不可以有的输入框长有的短。着重几点
1.关于form表单应该如何水平布局
在element中form有个属性叫:inlinetrue时候就会水平。但是有问题有的输入框比较长像日期选择器和普通输入框大小就不一致。此时就不应该使用这个属性。应该用el-row,el-col。因为输入框默认是独占一行的就像div
代码如下 el-form :modelqueryParams refqueryForm label-width80pxel-row :gutter20el-col :span8el-form-item label考核年度 propappraisalYearel-date-pickerv-modelqueryParams.appraisalYeartypeyearplaceholder选择年value-formatyyyy-MM-dd/el-date-picker/el-form-item/el-colel-col :span8el-form-item label负责人 propuserIdel-select v-modelqueryParams.userId placeholder请选择el-optionv-for(item, index) in userList:keyindex:labelitem.nickName:valueitem.userId/el-option/el-select/el-form-item/el-colel-col :span8el-button typeprimary iconel-icon-search clickhandleQuery查询/el-buttonel-button iconel-icon-refresh-right clickresetQuery重置/el-button/el-col/el-row/el-form 2.当form表单过多时如何布局
添加一个模板 template v-ifadvanced利用advanced去控制遮住还是隐藏 el-form :modelqueryParams refqueryForm label-width80pxel-row :gutter20el-col :span8el-form-item label时间 propdateel-date-pickerv-modelqueryParams.datetypedaterangerange-separator至start-placeholder开始日期end-placeholder结束日期/el-date-picker/el-form-item/el-colel-col :span8el-form-item label名称 proptaskNameel-inputv-modelqueryParams.taskNameplaceholder请输入clearable//el-form-item/el-coltemplate v-ifadvancedel-col :span8el-form-item label紧急程度 proplevelel-select v-modelqueryParams.level placeholder请选择el-option label一般 value0/el-optionel-option label急 value1/el-optionel-option label紧急 value2/el-option/el-select/el-form-item/el-colel-col :span8el-form-item label阅读状态 propisReadel-select v-modelqueryParams.isRead placeholder请选择el-option label未读 value0/el-optionel-option label已读 value1/el-option/el-select/el-form-item/el-colel-col :span8el-form-item label任务状态 propstatusel-select v-modelqueryParams.status placeholder请选择el-option label未开始 value0/el-optionel-option label进行中 value1/el-optionel-option label已提交 value2/el-optionel-option label已完成 value3/el-option/el-select/el-form-item/el-col/templateel-col :span8div stylemargin-left: 30pxel-button typeprimary iconel-icon-search clickhandleQuery查询/el-buttonel-button iconel-icon-refresh-right clickresetQuery重置/el-buttona clicktoggleAdvanced stylemargin-left: 16px{{ advanced ? 收起 : 展开 }}i:classadvanced ? el-icon-arrow-up : el-icon-arrow-down/i/a/div/el-col/el-row/el-form
3.业务逻辑
重点先说说详情编辑行复制删除导入导出多选框的表格单选框的表格时间搜索vue2数组和表单数据的渲染文件的回显图片的回显还有es6语法js逻辑。
1.详情
详情的话可以取决于你的页面是否和新增长的一样如果长的一样可以表单控制一个disabled属性来控制禁止输入
例子 el-form-item label考核年度 propfulfillYearel-date-pickerv-modelform.fulfillYeartypeyearplaceholder选择年度value-formatyyyy:disableddisabled/el-date-picker/el-form-item 2.新增
外层的新增和编辑我会使用一个页面没啥好说的。重点是内层新增她还可以编辑这个重点。如何编辑完可以拿到回调的值这个难。
在编辑的页面增加一个标识符判断编辑还是新增 save() {console.log(this.form, this.form);// this.$emit(getList, this.form);this.$emit(getList, {...this.form,addType: this.title 新增考评指标 ? add : edit,time: new Date().getTime(),});this.innerVisible false;},
在新增的页面判断是新增还是编辑 getList(value) {let newAddData [];console.log(我收到了子组件新增标准的值, value);if (value.addType edit) {// 创建一个与this.tableData相同结构和内容的新数组// 使用JSON.parse(JSON.stringify(object))来深拷贝对象避免直接修改原对象let marr JSON.parse(JSON.stringify(this.tableData));// marr.forEach((item, index) {// if (index value.index) {// item value;// }// });marr[value.index] value;console.log(marr);this.tableData marr;console.log(marr);} else {if (Array.isArray(value)) {newAddData [...this.tableData, ...value];} else {// 若 res.data 不是数组将其包装成数组再进行合并newAddData [...this.tableData, value];}// const newList [...this.tableData, value];this.tableData newAddData;// this.tableData.sort((a, b) {// // 先按照sort字段降序排序// if (a.sort ! b.sort) {// return a.sort - b.sort;// } // 如果sort相同则按照time字段升序排序转换为毫秒// else {// return b.time - a.time;// }// });}// const newList [...this.tableData, value];// this.tableData newList;console.log(this.tableData, this.tableData);console.log(this.deptOptions, this.deptOptions);// 遍历tableData数组根据deptId查找对应的labelthis.tableData this.tableData.map((item) {const deptName this.findLabelById(item.deptId, this.deptOptions);const userIds item.userIds?.split(,);if (userIds) {const userNames userIds.map((item2) {const user this.userList.find((item3) item3.userId item2);// console.log(userNames, userNames);return user ? user.nickName : null;}).join(,);return { ...item, deptName, userNames };} else {return { ...item, deptName };}});console.log(this.tableData, this.tableData);},
这边要注意什么是浅拷贝和深拷贝我之前都是浅拷贝这边要改成深拷贝深拷贝的话避免直接修改原对象。
3.编辑
编辑的话通常后台需要传当前行的数据进去后端会提供一个id,去查找数据数据回显就好了。主要是文件和图片的回显看下面
4.行复制
代码如下 深拷贝一个对象这样不会影响原对象 delete copy.createTime;删除对象属性 es6语法这边的逻辑就是复制一个和原对象无关的对象然后用接口新增。 这边重点是es6语法和深浅拷贝的了解与引用
1.深拷贝
const copy JSON.parse(JSON.stringify(row));
2. 浅拷贝 const copy Object.assign({}, row);
如果修改的是第一层直接属性且它们是原始类型row 不受影响如果修改的是第一层直接属性且它们是引用类型如其他对象或数组实际上是在修改共享的嵌套对象此时 row 会相应地发生改变。例子如下 const row {name: John,address: {street: Main St.,number: 123,},
};const copy Object.assign({}, row);// 修改第一层属性字符串不影响 row
copy.name Jane; // row.name仍然是John// 修改嵌套对象的属性会影响 row
copy.address.street New St.; // row.address.street现在也是New St. async copyRow(row) {console.log(row, row);// this.loading true;const copy JSON.parse(JSON.stringify(row));delete copy.createTime;copy.dutyAppraisalId null;copy.status nullcopy.isRead 0copy.progress 0console.log(copy, copy);await this.getDetail(row.dutyAppraisalId);addDemo({status: 0,type: 0,...copy,dutyItems: this.tableData,}).then((res) {if (res.code 200) {this.$message({message: 新建成功,type: success,});this.loading false;this.getList();}});// .finally(() {// this.loading false;// });}, 5.删除
在这个项目中有3中删除
第一种利用接口拿到id接口删除 del(No, data) {// console.log(No, No, DATA, data);if (data.workItemId) {delDetailList(data.workItemId).then((res) {if (res.code 200) {this.$message({message: 删除成功,type: success,});this.deleteFuc(No, data);}});} else {this.deleteFuc(No, data);}},
第二种不需要调用接口时候利用filter es6的语法 // 使用数组的filter方法传入一个回调函数作为筛选条件// 回调函数接受当前遍历项item作为参数检查其No属性是否与传入的No参数相异// 若相异则保留该项否则过滤掉const filterData this.originalData.filter((item) {return item.No ! No;});
第三种直接用数组splice this.fileList.splice(index, 1); 6.导入
三部曲
第一步 el-uploadclassupload-demo:actionuploadFileUrlmultiple:show-file-listfalse:headersheaders:on-successhandleUploadSuccessel-button导入/el-button/el-upload
第二步定义 id不存在存在不确定存不存在的写法都在下方
import { getToken } from /utils/auth;
export default {components: { contentSet, editStandard },data() {return {activeName: first,activeName2: first,form: {},title: ,dialogVisible: false,// 接收数据tableData: [],updatedData: [],// 字典值List: [],showData: [], //展示数据originalData: [], //真正的数据// rowData: {}, //行数据uploadFileUrl: ${process.env.VUE_APP_BASE_API}/epb/workItem/importData${this.form this.form.id ? ?workId this.form.id : },// uploadFileUrl: ${process.env.VUE_APP_BASE_API}/epb/workItem/importData?workId${this.form.id}, // 上传文件服务器地址// uploadFileUrl: process.env.VUE_APP_BASE_API /epb/workItem/importData, // 上传文件服务器地址headers: {Authorization: Bearer getToken(),},show: false,workList: [],loading: false,};},
第三步 // 导入文件handleUploadSuccess(res, file) {// console.log(res, res, file, file);if (res.code 200) {//深拷贝let mArr JSON.parse(JSON.stringify(tableData));// 页面操作 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组而是返回一个新数组。mArr mArr.concat(res.data.workItemVos);mArr mArr.map((item, index) {return {...item,sort: item.sort 1, //一开始就遍历加上序号markTime: new Date().getTime(),};});// console.log(mArr, mArr);this.getContentList(mArr);// this.workList [];this.workList this.workList.concat(res.data.workLabelVos);console.log(this.workList, this.workList);}}, 7.导出 el-buttontypeprimaryplainiconel-icon-downloadclickhandleExport导出/el-button/** 导出按钮操作 */handleExport() {this.download(/epb/dutyFulfill/export,{...this.queryParams,},责任落实档案列表.xlsx);}, 8.多选框的表格 9.单选框的表格 10.时间搜索 getList() {// this.getTime();let mData Object.assign({pageNum: this.pagination.current,pageSize: this.pagination.pageSize,},// this.queryParams{...this.queryParams,startTime: this.queryParams?.date?.length ? dayjs(this.queryParams.date[0]).format(YYYY-MM-DD) : undefined,endTime: this.queryParams?.date?.length 1 ? dayjs(this.queryParams.date[1]).format(YYYY-MM-DD) : undefined,});mData.createUserId store.getters.userId;this.loading true;listDemo(mData).then((res) {if (res.code 200) {console.log(res, res);this.remindersList res.rows;console.log(this.remindersList, this.remindersList);this.pagination.total res.total;this.loading false;}}).finally(() {this.loading false;});}, 11.对象的键名 // const obj {// a: 1,// b: 2,// c: []// }// obj[c]就是数组拿到的是obj.c的值可以用push groupAndMergeData(arr) {// console.log(a2222, arr);let groupedData {}; // 遍历newAddData按workContent字段分类arr.forEach((item) {// const obj {// a: 1,// b: 2,// c: []// }// obj[c]就是数组拿到的是obj.c的值可以用pushif (!groupedData[item.workContent]) {// [item.workContent]表示键名groupedData[item.workContent] [item];} else {groupedData[item.workContent].push(item);// groupedData[item.workContent].sort((a, b) a.sort - b.sort);groupedData[item.workContent].sort((a, b) {// 先按照sort字段降序排序if (a.sort ! b.sort) {return a.sort - b.sort;} // 如果sort相同则按照time字段升序排序转换为毫秒else {return b.markTime - a.markTime;}});}});// console.log(arr11111, arr);// console.log(groupedData, groupedData);// 合并所有子数组let mergedData [];for (let category in groupedData) {mergedData [...mergedData, ...groupedData[category]];}// console.log(mergedData, mergedData);// 全部数据保存到这个真正的数据里const sortData [...mergedData].map((item, index) {return {...item,No: index 1, //一开始就遍历加上序号};});return sortData;},分组 一种是对象的分组一种的数组的分组
数组的分组 let classifyWorkContentList []; //类别数组[...sourceData].forEach((item) {// .includes()方法返回一个布尔值true或falseif (classifyWorkContentList.indexOf(item.workContent) -1) {classifyWorkContentList.push(item.workContent);}});
12.文件的回显 const fileArr data?.fileUrl?.split(,)?.map((item, index) {return {fileUrl: item,fileName: data?.fileName?.split(,)[index],};}) || [];this.form data;this.$set(this.form, fileList, fileArr);el-descriptions-item label附件 :span2span v-for(item, index) in form.fileList :keyindexa :hrefitem.fileUrl target_blank{{ item.fileName }}/a,/span/el-descriptions-item 这边的index因为fileUrl和fileName不是一个数组里的,俩个本来是俩个字符串然后用split分隔成俩个数组这边的操作就是把它们弄到一个数组里
13.图片的回显
templatedivel-image v-for(item,index) in realSrcList :keyindex:src${item}fitcover:stylewidth:${realWidth};height:${realHeight};:preview-src-listrealSrcListdiv sloterror classimage-sloti classel-icon-picture-outline/i/div/el-image/div/templatescriptexport default {name: ImagePreview,props: {src: {type: String,default: },width: {type: [Number, String],default: },height: {type: [Number, String],default: }},computed: {realSrc() {if (!this.src) {return;}let real_src this.src.split(,)[0];return real_src;},realSrcList() {if (!this.src) {return;}let real_src_list this.src.split(,);let srcList [];real_src_list.forEach(item {return srcList.push(item);});return srcList;},realWidth() {return typeof this.width string ? this.width : ${this.width}px;},realHeight() {return typeof this.height string ? this.height : ${this.height}px;}},
};
/scriptstyle langscss scoped
.el-image {border-radius: 5px;background-color: #ebeef5;box-shadow: 0 0 5px 1px #ccc;::v-deep .el-image__inner {transition: all 0.3s;cursor: pointer;:hover {transform: scale(1.2);}}::v-deep .image-slot {display: flex;justify-content: center;align-items: center;width: 100%;height: 100%;color: #909399;font-size: 30px;}
}
/style父组件 ImagePreview:srcform.picUrl:width150:height150/ImagePreview 14.es6语法
map,filter 15.js逻辑关于党务工作清单的
第一步要先判断是编辑还是新增。第二步要确定传给后端的格式。第三步展示数据的格式。第四步删除的排序要判断是有id的还是直接删除。第五步当导入进来的时候相当于新增要进行说明新增的时候要进行判断如果是数据还是对象。第六步对于这种提交数据和展示数据不一样数据格式时候要注意操作。
第一步 getContentList(value) {// console.log(我收到子组件传递的值, value);let newData [];let newAddData [];if (value.addType edit) {// console.log(this.originalData, this.originalData);newData this.originalData.map((item) {if (item.No value.No) {return value;}return item;});} else {if (Array.isArray(value)) {newData [...this.originalData, ...value];} else {// 若 res.data 不是数组将其包装成数组再进行合并newData [...this.originalData, value];}}// console.log(value111, value);// console.log(更新后的newData:, newData);const sortData this.groupAndMergeData(newData);// 赋值给真正的数组this.originalData sortData;// console.log(sortData时间字段, sortData);// 赋值给展示数据this.showData this.handleData(sortData);},
数据分类 // 分类排序groupAndMergeData(arr) {// console.log(a2222, arr);let groupedData {}; // 遍历newAddData按workContent字段分类arr.forEach((item) {// const obj {// a: 1,// b: 2,// c: []// }// obj[c]就是数组拿到的是obj.c的值可以用pushif (!groupedData[item.workContent]) {// [item.workContent]表示键名groupedData[item.workContent] [item];} else {groupedData[item.workContent].push(item);// groupedData[item.workContent].sort((a, b) a.sort - b.sort);groupedData[item.workContent].sort((a, b) {// 先按照sort字段降序排序if (a.sort ! b.sort) {return a.sort - b.sort;} // 如果sort相同则按照time字段升序排序转换为毫秒else {return b.markTime - a.markTime;}});}});// console.log(arr11111, arr);// console.log(groupedData, groupedData);// 合并所有子数组let mergedData [];for (let category in groupedData) {mergedData [...mergedData, ...groupedData[category]];}// console.log(mergedData, mergedData);// 全部数据保存到这个真正的数据里const sortData [...mergedData].map((item, index) {return {...item,No: index 1, //一开始就遍历加上序号};});return sortData;}, 重点是对象键名 变数组 // const obj {// a: 1,// b: 2,// c: []// }// obj[c]就是数组拿到的是obj.c的值可以用push 展示数据处理 // 处理数据handleData(sourceData) {// 分类let classifyWorkContentList []; //类别数组[...sourceData].forEach((item) {// .includes()方法返回一个布尔值true或falseif (classifyWorkContentList.indexOf(item.workContent) -1) {classifyWorkContentList.push(item.workContent);}});console.log(classifyWorkContentList, classifyWorkContentList);// 按照表格样式修改数据结构// 例如[{workContent: xxx, workNormList: [{workItemId: 1111,workId: 11111 ,workContent:xxx,sort: 1,workNorm:xxx,No: 1,isDone: 0}]const handleData classifyWorkContentList.map((item) {return {workContent: item,workNormList: sourceData.filter((item2) item2.workContent item),};});return handleData;}, 删除数据 deleteFuc(No, data) {const filterData this.originalData.filter((item) {return item.No ! No;});const sortData filterData.map((item, index) {return {...item,No: index 1, //一开始就遍历加上序号};});this.originalData sortData;// 赋值给展示数据this.showData this.handleData(sortData);},// 删除del(No, data) {// console.log(No, No, DATA, data);if (data.workItemId) {delDetailList(data.workItemId).then((res) {if (res.code 200) {this.$message({message: 删除成功,type: success,});this.deleteFuc(No, data);}});} else {this.deleteFuc(No, data);}}, 导入文件 // 导入文件handleUploadSuccess(res, file) {// console.log(res, res, file, file);if (res.code 200) {const tableData [];let mArr JSON.parse(JSON.stringify(tableData));// 页面操作 concat() 方法用于合并两个或多个数组。此方法不会更改现有数组而是返回一个新数组。mArr mArr.concat(res.data.workItemVos);mArr mArr.map((item, index) {return {...item,sort: item.sort 1, //一开始就遍历加上序号markTime: new Date().getTime(),};});// console.log(mArr, mArr);this.getContentList(mArr);// this.workList [];this.workList this.workList.concat(res.data.workLabelVos);console.log(this.workList, this.workList);}}, 16.树形下拉框
子组件
templatediva-tree-selectv-modelorgIdstylewidth: 100%sizelarge:dropdown-style{ maxHeight: 400px, overflow: auto, zIndex: 3000 }placeholder请选择allow-cleartree-default-expand-all:disableddisabled:tree-datavorganTreeData:replaceFieldsreplaceFieldschangeonChange/a-tree-select/div
/templatescript
//注意
//在modal弹窗组件中使用该组件需要在关闭弹窗方法里清空数据否则会报错
import { userdepList } from /api/user/user;
export default {name: vorganTree,props: {value: {// 如果希望value可以接收int类型的值而不报错可以将type类型修改为可以兼容字符串和整数的类型type: [String, Number],default: ,},disabled: {type: Boolean,default: false,},replaceFields: {type: Object,default: () {return {children: children,title: label,key: id,value: id,};},},},data() {return {orgId: this.value,vorganTreeData: [],deptId: ,};},watch: {value: {handler(newVal) {this.orgId newVal;},immediate: true,},},mounted() {// this.$bus.$on(id, (data) {// console.log(我是任务组件,收到了数据, data);// this.deptId data;// });this.deptId this.$bus.id;this.userdepList();},methods: {userdepList() {userdepList({ ancestors: this.deptId }).then((res) {console.log(res.data, res);this.vorganTreeData res.data;});},selectClear() {this.orgId undefined;},onChange(value, item, xx) {console.log(11111, value, item, xx);// this.$emit(update:value, value);this.$emit(getdep, value);},},
};
/scriptstyle scoped langless
/style父组件 orginTree v-modelform.deptId getdepgetdep/orginTree 17.时间的回显
this.$set(this.form, date, [dayjs(data.startTime).format(YYYY-MM-DD),dayjs(data.endTime).format(YYYY-MM-DD),]);
18.富文本去除标签 富文本组件事Editor Editor v-modelform.requirement :height100/Editor// 提交数据时去除p标签const processedRequirement that.form.requirement?.replace(/\/?p/g,);
19.props接收兼容性写法 props: {value: {// 如果希望value可以接收int类型的值而不报错可以将type类型修改为可以兼容字符串和整数的类型type: [String, Number],default: ,},disabled: {type: Boolean,default: false,},replaceFields: {type: Object,default: () {return {children: children,title: label,key: id,value: id,};},},},
20.文本的总体代码
templatediv classupload-fileel-uploadv-ifisUploadmultiple:actionuploadFileUrl:before-uploadhandleBeforeUpload:file-listfileList:limitlimit:on-errorhandleUploadError:on-exceedhandleExceed:on-successhandleUploadSuccess:show-file-listfalse:headersheadersclassupload-file-uploaderreffileUpload!-- 上传按钮 --el-button sizemini typeprimary选取文件/el-button!-- 上传提示 --div classel-upload__tip slottip v-ifshowTip请上传template v-iffileSize大小不超过 b stylecolor: #f56c6c{{ fileSize }}MB/b/templatetemplate v-iffileType格式为 b stylecolor: #f56c6c{{ fileType.join(/) }}/b/template的文件/div/el-upload!-- 文件列表 --transition-group classupload-file-list el-upload-list el-upload-list--text nameel-fade-in-linear tagul v-ifisFileListli :keyfile.url classel-upload-list__item ele-upload-list__item-content stylepadding: 0 4px v-for(file, index) in fileListel-link :href${file.url} :underlinefalse target_blankspan classel-icon-document {{ getFileName(file.name) }} /span/el-linkdiv classele-upload-list__item-content-action v-ifisUploadel-link :underlinefalse clickhandleDelete(index) typedanger删除/el-link/div/li/transition-group/div
/templatescript
import { getToken } from /utils/auth;
import { listByIds, delOss } from /api/system/oss;export default {name: FileUpload,props: {// 值value: [String, Object, Array],// 数量限制limit: {type: Number,default: 5,},// 大小限制(MB)fileSize: {type: Number,default: 5,},// 文件类型, 例如[png, jpg, jpeg]fileType: {type: Array | Boolean,default: () [doc, xls, ppt, txt, pdf],},// 是否显示提示isShowTip: {type: Boolean,default: true,},// 是否显示文件列表isFileList: {type: Boolean,default: true,},dataIndex: {type: Number | String,default: 0,},// 是否可以上传isUpload: {type: Boolean,default: true,},},data() {return {number: 0,uploadList: [],baseUrl: process.env.VUE_APP_BASE_API,uploadFileUrl: process.env.VUE_APP_BASE_API /system/oss/upload, // 上传文件服务器地址headers: {Authorization: Bearer getToken(),},fileList: [],};},watch: {value: {async handler(val) {if (val) {let temp 1;// 首先将值转为数组let list;if (Array.isArray(val)) {list val;} else {console.log(val);await listByIds(val).then((res) {list res.data.map((oss) {oss {name: oss.originalName,url: oss.url,ossId: oss.ossId,};return oss;});this.$emit(getfile, list, this.dataIndex);});}// 然后将数组转为对象数组this.fileList list.map((item) {item { name: item.name, url: item.url, ossId: item.ossId };item.uid item.uid || new Date().getTime() temp;return item;});} else {this.fileList [];return [];}},deep: true,immediate: true,},},computed: {// 是否显示提示showTip() {return this.isShowTip (this.fileType || this.fileSize);},},methods: {// 上传前校检格式和大小handleBeforeUpload(file) {// 校检文件类型if (this.fileType) {const fileName file.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 file.size / 1024 / 1024 this.fileSize;if (!isLt) {this.$modal.msgError(上传文件大小不能超过 ${this.fileSize} MB!);return false;}}this.$modal.loading(正在上传文件请稍候...);this.number;return true;},// 文件个数超出handleExceed() {this.$modal.msgError(上传文件数量不能超过 ${this.limit} 个!);},// 上传失败handleUploadError(err) {this.$modal.msgError(上传文件失败请重试);this.$modal.closeLoading();},// 上传成功回调handleUploadSuccess(res, file) {if (res.code 200) {this.uploadList.push({name: res.data.fileName,url: res.data.url,ossId: res.data.ossId,});this.uploadedSuccessfully();} else {this.number--;this.$modal.closeLoading();this.$modal.msgError(res.msg);this.$refs.fileUpload.handleRemove(file);this.uploadedSuccessfully();}},// 删除文件handleDelete(index) {let ossId this.fileList[index].ossId;// delOss(ossId);this.fileList.splice(index, 1);this.$emit(input, this.listToString(this.fileList));},// 上传结束处理uploadedSuccessfully() {if (this.number 0 this.uploadList.length this.number) {this.fileList this.fileList.concat(this.uploadList);this.uploadList [];this.number 0;this.$emit(input, this.listToString(this.fileList));this.$modal.closeLoading();}},// 获取文件名称getFileName(name) {// 如果是url那么取最后的名字 如果不是直接返回if (name.lastIndexOf(/) -1) {return name.slice(name.lastIndexOf(/) 1);} else {return name;}},// 对象转成指定字符串分隔listToString(list, separator) {let strs ;separator separator || ,;for (let i in list) {strs list[i].ossId separator;}return strs ! ? strs.substr(0, strs.length - 1) : ;},},
};
/scriptstyle scoped langscss
.upload-file-uploader {margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {border: 1px solid #e4e7ed;line-height: 2;margin-bottom: 10px;position: relative;
}
.upload-file-list .ele-upload-list__item-content {display: flex;justify-content: space-between;align-items: center;color: inherit;
}
.ele-upload-list__item-content-action .el-link {margin-right: 10px;
}
/style父组件 el-table-column label操作 propaction width100template slot-scopescope!-- el-upload classupload-demo actionhttps://jsonplaceholder.typicode.com/posts/ :on-changehandleChange :show-file-listfalseel-button sizesmall typeprimary点击上传/el-button/el-upload --FileUploadv-modeltableData[scope.$index].materialIds:dataIndexscope.$index:isShowTipfalse:fileTypefalse:isFileListfalse:isUploadscope.row.status 3 || scope.row.status 0 || scope.row.status nullgetfilegetfile/FileUpload/template/el-table-column