在 Vue + elementUi 开发中,当某些新增表单数据过多时,为了提高新增数据的效率,往往会需要实现批量新增的功能。为此,我们就需要封装一个批量新增弹窗的功能组件,因实际场景需要,本次封装的批量导入组件,涵盖附件上传功能,组件仅以抛砖引玉! 需要按照实际应用场景进行调整!
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
url | 批量导入模板文件上传地址 | String | - | 必填 |
title | 批量导入标题 | String | - | 批量导入 |
uploadTableFileUrl | 模板导入列表数据中附件上传地址 | String | - | 必填 |
restrictFileTypes | 模板文件可上传附件类型限制 | Array | ‘xlsx’, ‘xls’…文件类型 | [ ] |
fileName | 模板文件流入参名称 | String | - | files |
fileData | 模板上传参数Data | Object | - | null |
downFileName | 模板下载按钮文本 | String | - | 下载 |
columnArray | 附件列表表头配置(需与后端沟通) | Array | - | [ ] |
tableTypeOpinion | 列表类型切换配置参数 | Array | - | [{label: ‘类型一’,value: ‘类型一’}…] |
tableApi | 获取列表数据的Axios 方法名称,需要按照应用场景封装的Axios请求方式 修改组件内部代码 |
String | - | 必填 |
fileDeleteApi | 模板数据列表中的Axios 方法名称,需要按照应用场景封装的Axios请求方式 修改组件内部代码 |
String | - | 必填 |
uploadFileIdName | 列表附件上传入参时对应的ID名称 | String | - | id |
rowFileIdName | 列表数据的ID名称,与uploadFileIdName 配合使用,uploadFileIdName 入的参数为rowFileIdName对应的值 | String | - | id |
outSideDownFn | 父组件中对应的下载模板的方法名 | String | - | 必填 |
outSideShowName | 外部引用子组件的显隐判断参数名 | String | - | showFileUp |
showTableType | 控制是否显示列表类型切换功能 | Boolean | - | false |
tableTypeName | 列表类型切换时,请求列表入参名 | String | - | tableType |
importDataTips | 导入提示 | String | - |
方法名 | 说明 | 参数 |
---|---|---|
tableTypeChange | 列表类型切换组件发生变更时触发 | change值 |
upLoadSuccess | 导入模板文件成功时触发 | 文件上传接口返回res |
getRow | 列表操作方法对应点击触发方法 | 操作事件类型,与columnArray 配置中定义的配置相关 |
submit | 点击保存时触发 | 请求参数 |
<fileUploads
ref="fileUploads"
v-if="showFileUploads"
outSideShowName="showFileUploads"
title="批量导入核实数据"
:downFileName="'已选中 ' + (multipleSelection.length || 0) + ' 条数据,点击下载模板'"
fileName="excelFile"
url="/disposal/modelOrder/batchCheck/importExcel"
:fileData="{}"
fileDeleteApi="knowledgeExcelImportDeleteFile"
importDataTips="提示: 导入批量核实模板明细选项条数最多不能超过1000条"
:columnArray="columnArray_file"
:exportMark="'knowledge' + $route.query.itemIndex"
uploadTableFileUrl="/disposal/modelOrder/batchCheck/uploadFile"
tableApi="disposalModelOrderBatchCheckImportList"
:restrictFileTypes="['xlsx', 'xls']"
uploadFileIdName="id"
outSideDownFn="fileModelDownFn"
:showTableType="true"
:tableTypeOpinion="[
{
label: '非缺陷',
value: 1
},
{
label: '缺陷',
value: 2
}
]"
tableTypeName="tableType"
@tableTypeChange="getColumnArray_batch"
@upLoadSuccess="upLoadSuccess($event)"
@getRow="getRow"
@submit="fileUploadsSubmit"
/>
// 数据
columnArray: [
{
prop: "problemCode",
label: "问题编号",
width: "150",
},
{
prop: "problemFindTime",
label: "问题发现时间",
width: "165",
},
{
prop: "problemDescription",
label: "问题具体描述",
width: "160",
},
{
prop: "problemExistOrgName",
label: "问题整改情况",
width: "140",
},
{
type: "files",
prop: "files",
label: "附件名称",
width: "140",
showOverflowTooltip: false,
},
{
type: "uploadFile",
prop: "files",
label: "上传附件",
width: "140",
},
{
type: "operate",
linkName: ["删除"],
label: "操作",
width: "100",
},
],
// 方法
<script>
// 获取表格表头
async getColumnArray_batch(type, fn = () => {}) {
const res = await this.getDictionaryHeader({
code: 'batch-' + type,
ssywy: this.paramsInfo.data.ywy
})
if (Array.isArray(res) && res.length !== 0) {
this.columnArray_file = [
...res,
// {
// type: "uploadFile",
// prop: "files",
// label: "上传附件",
// width: "140",
// },
{
type: "operate",
linkName: ["删除"],
label: "操作",
width: "100",
},
]
fn()
} else {
this.columnArray_file = []
this.$message.warning('批量核实需上传列表表头获取失败,请重试!')
}
return false;
},
// 批量核实部分代码
// 批量导入 - 导入文件成功
upLoadSuccess(res) {
this.$refs["fileUploads"].initTable({
versionId: res.data,
ssywy: this.paramsInfo.data.ywy
});
},
// 批量导入表格操作
getRow(row, type) {
if (type == "删除") {
this.disposalModelOrderBatchCheckImportListDelete({
knowledgeId: row.id,
}).then(() => {
// window.console.log(res)
this.$message.success("删除成功!");
this.$refs["fileUploads"].initTable();
});
} else if (type == "下载") {
// this.downloadFile(row)
}
},
// 批量导入提交
fileUploadsSubmit(params) {
let _params = new URLSearchParams();
for (let key in params) {
_params.append(key, params[key]);
}
this.disposalModelOrderBatchCheckSubmit(_params)
.then(() => {
// window.console.log(res)
this.$message.success("批量导入成功!");
this.$refs["fileUploads"].closeDialog();
this.getDocumentQuery();
})
.catch((err) => {
this.$message.warning(err.message || "请求出错,请检查后重试!");
});
},
script>
<template>
<div
:class="
$root.themeHomeChange === '1'
? 'fileUpload fileUpload_light'
: 'fileUpload'
"
>
<bda-dialog
:visible="dialogVisible"
:modal="false"
:close-on-click-modal="false"
@cancel="closeDialog"
@close="closeDialog"
:title="title"
:modal-append-to-body="false"
>
<div class="dialogBox">
<div class="header">
<el-row
style="font-size: 1.125rem; line-height: 30px; padding: 15px 15px 0;"
>
<el-col :span="12" class="upload-box">
<span class="title">导入数据:span>
<el-upload
ref="uploaddemo"
class="upload-demo"
:limit="1"
:data="fileData"
:name="fileName"
:action="fileUrl"
:multiple="false"
:on-change="handleChange"
:on-exceed="handleExceed"
:before-upload="beforeAvatarUpload"
:on-success="handleAvatarSuccess"
:show-file-list="false"
:file-list="fileList"
>
<el-button size="mini" style="margin-left:10px">上传el-button>
el-upload>
<span class="text" v-if="fileList.length">
已上传:
<span v-for="(item, index) in fileList" :key="index">
{{ item.name }}
<el-button
type="text"
@click="handleClick('remove', item, index)"
>删除el-button
>
span>
span>
el-col>
<el-col :span="12">
<span class="title">模板下载:span>
<el-button
size="mini"
:loading="exportLoading"
@click="handleClick('down')"
>{{ downFileName }}el-button>
el-col>
el-row>
<el-row
style="font-size: 1.125rem; line-height: 30px; padding: 15px 15px 0;"
>
<span class="title">导入结果:span>
<strong v-if="importData !== 0">导入成功,导入数据{{ importData }}条strong>
<strong v-else>暂无导入文件,请先导入文件!strong>
<p v-if="!!importDataTips" style="margin: 8px 0 0 0; color: #fc6271; font-weight: bold;">{{ importDataTips }}p>
el-row>
div>
<div class="line">div>
<div class="tableHeader_1">
<span class="name">需上传附件列表span>
<el-radio-group
v-model="params[tableTypeName]"
v-if="showTableType"
@change="tableTypeChange"
>
<el-radio-button
v-for="(item, index) in tableTypeOpinion"
:key="index"
:label="item.value"
>{{ item.label }}el-radio-button>
el-radio-group>
div>
<el-table
v-loading="tableLoading"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
:data="tableData"
row-key="knowledgeId"
ref="table"
tooltip-effect="light"
height="300"
popper-append-to-body
>
<el-table-column
type="index"
label="序号"
width="70"
align="center"
>el-table-column>
<el-table-column
v-for="(item, index) in columnArray"
:show-overflow-tooltip="
item.showOverflowTooltip == undefined
? true
: item.showOverflowTooltip
"
:key="index"
:prop="item.prop"
:label="item.label"
:min-width="item.width"
align="center"
>
<template slot-scope="scope">
<span v-if="item.type === 'operate'">
<el-button
type="text"
v-for="item2 in item.linkName"
:key="item2"
@click="rowClick(scope.row, item2)"
>{{ item2 || "" }}el-button
>
span>
<template v-else-if="item.type === 'files'">
<el-popover
popper-class="popoverClass_light"
v-if="scope.row[item.prop].length !== 0"
placement="top-start"
width="200"
trigger="hover"
>
<div
class="table_file"
v-for="(item_1, index_1) in scope.row[item.prop]"
:key="index_1"
@click="rowClick(item_1, '下载')"
>
{{ "附件 [" + (index_1 + 1) + "]: " + item_1.fileName }}
div>
<p slot="reference" class="fileTitle">
{{ "附件 [1]: " + scope.row[item.prop][0].fileName }}
p>
el-popover>
<p v-else>暂无数据p>
template>
<template v-else-if="item.type === 'uploadFile'">
<el-button @click="showUploadFileDialog(scope.row, scope.row[item.prop])" >{{ scope.row[item.prop].length !== 0 ? '修改已上传文件' : '选择文件' }}el-button>
template>
<span v-else>{{ scope.row[item.prop] }}span>
template>
el-table-column>
el-table>
<el-pagination
:disabled="params.total == 0"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="params.current"
:page-sizes="[10, 50, 100, 200]"
:page-size="params.size"
background
layout="prev, pager, next, sizes, jumper, total"
:total="params.total"
>el-pagination>
<el-dialog
title="附件操作"
:modal="false"
:visible.sync="innerVisible"
custom-class="uploadFiles"
>
<el-input
v-show="false"
v-model="tableFileParams.fileTable.length">
el-input>
<p style="font-size: 12.5px; line-height: 25px; margin-bottom: 10px;">
(单个文件大小不能超过50M,仅支持 xls、xlsx、doc、docx、pdf 格式)
p>
<el-upload
class="upload-demo"
name="files"
ref="uploaddemo_table"
:action="tableFileParams.fileUrl"
:data="tableFileParams.data"
:on-change="handleChange_table"
:before-upload="beforeAvatarUpload_table"
:on-success="handleAvatarSuccess_table"
:file-list="tableFileParams.fileList"
>
<el-button
size="small"
plain
>上传附件el-button>
el-upload>
<el-table
:data="tableFileParams.fileTable"
style="width: 100%; margin-top: 10px;"
height="calc(170px)"
v-loading="tableFileParams.fileTableLoading"
tooltip-effect="light"
element-loading-text="拼命加载中"
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(0, 0, 0, 0.8)"
>
<el-table-column
type="index"
label="序号"
width="60"
align="center"
>el-table-column>
<el-table-column
prop="fileName"
label="附件名称"
min-width="120"
align="center"
show-overflow-tooltip>
el-table-column>
<el-table-column
prop="fileType"
label="类型"
width="120"
align="center"
show-overflow-tooltip>
el-table-column>
<el-table-column
label="操作"
width="100"
align="center"
>
<template slot-scope="scope">
<el-button
type="text"
style="margin-left: 0;"
@click="deleteFile(scope.row)"
> 删除 el-button>
template>
el-table-column>
el-table>
<span slot="footer" class="dialog-footer">
<el-button @click="tableFileSubmit" type="primary">保 存el-button>
<bda-button bdatype="defualt" @click="closeFileDialog">关闭bda-button>
span>
el-dialog>
div>
<span slot="footer" class="dialog-footer">
<el-button @click="submit()" type="primary">保 存el-button>
<bda-button bdatype="defualt" @click="closeDialog">关闭bda-button>
span>
bda-dialog>
div>
template>
<script>
import Interface from "@/base/mixin/enterprise-manage-center";
import Interface_1 from "@/base/mixin/risk-control-center";
import Interface_2 from "@/base/mixin/disposal-center.js";
import { API_PATH } from "@/config";
export default {
name: "historyDoc",
mixins: [Interface, Interface_1, Interface_2],
props: {
// 导入模板附件Url
url: {
type: String,
required:true,
default: () => {
return "";
},
},
// 列表附件上传API名称
uploadTableFileUrl: {
type: String,
required:true,
default: () => {
return "";
},
},
// 可上传附件类型
restrictFileTypes: {
type: Array,
default: () => {
return [];
},
},
// 附件上传的附件参数名
fileName: {
type: String,
default: () => {
return "files";
},
},
// 附件上传参数
fileData: {
type: Object,
default: () => {
return null;
},
},
// 标题
title: {
type: String,
default: () => {
return "批量导入";
},
},
// 下载模板提示文字
downFileName: {
type: String,
default: () => {
return "下载";
},
},
// 动态表头配置项
columnArray: {
type: Array,
required:true,
default: () => {
return [];
},
},
// 列表类型切换配置项
tableTypeOpinion: {
type: Array,
required:false,
default: () => {
return [
{
label: '类型一',
value: '类型一'
},
{
label: '类型二',
value: '类型二'
}
];
},
},
// 导出模板备注,用于区分多种模板时区分模板类型
exportMark: {
type: String,
default: () => {
return '';
},
},
// 获取列表数据API名称
tableApi: {
type: String,
required:true,
default: () => {
return '';
},
},
// 附件删除API名称
fileDeleteApi: {
type: String,
required:true,
default: () => {
return '';
},
},
// 对应列表项的id
uploadFileIdName: {
type: String,
default: () => {
return 'id';
},
},
// 列表项对应的附件ID名称,用于绑定附件操作等
rowFileIdName: {
type: String,
default: () => {
return 'id';
},
},
// 外部模板下载方法(名称)
outSideDownFn: {
type: String,
required:true,
default: () => {
return null;
},
},
// 外部入参
inParams: {
type: Object,
default: () => {
return {};
},
},
// 是否显示列表类型切换
showTableType: {
type: Boolean,
default: () => {
return false;
},
},
// 导入提示
importDataTips: {
type: String,
default: () => {
return null;
},
},
// 列表类型切换入参名称
tableTypeName: {
type: String,
default: () => {
return 'tableType';
},
},
// 外部控制显隐的字段,用于重新触发组件加载
outSideShowName: {
type: String,
default: () => {
return 'showFileUp';
},
},
},
data() {
return {
exportLoading: false,
tableLoading: false,
importData: 0,
dialogVisible: false,
innerVisible: false,
fileUrl: null,
fileList: [],
tableData: [],
// tableType: null,
in_Params: {},
params: {
current: 1,
size: 10,
total: 0,
},
tableFileParams: {
fileTable: [],
fileTableLoading: false,
fileList: [],
data: {},
fileUrl: ''
}
};
},
created() {
this.fileUrl = API_PATH + this.url;
this.tableFileParams.fileUrl = API_PATH + this.uploadTableFileUrl;
if(this.showTableType) {
window.console.log(1231)
this.params[this.tableTypeName] = this.tableTypeOpinion.length !== 0 ? this.tableTypeOpinion[0].value : null
}
},
mounted() {},
methods: {
/**
* @description:关闭弹框回调
*/
closeDialog() {
this.dialogVisible = false;
this.$parent[this.outSideShowName] = false;
this.initData()
},
// 初始化数据
initData() {
this.in_Params = {};
this.tableData = []
this.fileList = []
this.importData = 0
this.params = {
current: 1,
size: 10,
total: 0,
}
},
// 切换表格类型
tableTypeChange() {
this.$emit('tableTypeChange', this.params[this.tableTypeName])
if(this.fileList.length !== 0) {
this.initTable()
}
},
// 展示附件操作弹窗 并 进行参数传递
showUploadFileDialog(row, fileList) {
this.tableFileParams.data = {
...this.in_Params,
[this.uploadFileIdName]: row[this.rowFileIdName]
}
this.tableFileParams.fileTable = fileList.map(item => {
return {
...item,
fileType: item.fileType || (item.filePath && item.filePath.substring(item.filePath.lastIndexOf(".")+1))
}
})
this.innerVisible = true
},
rowClick(row, op) {
if (op === "删除") {
this.$confirm("此操作将删除该数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
window.console.log(row, op)
this.$emit("getRow", row, op);
})
} else {
this.$emit("getRow", row, op);
}
},
//文件上传成功钩子
handleAvatarSuccess(res) {
if (res.success) {
this.$message.success("上传成功");
this.$emit("upLoadSuccess", res);
} else {
this.$message.warning(
"上传失败, 失败原因:" +
((res.message || res.code) ? (res.message || res.code) : "未知")
);
this.$refs.uploaddemo.clearFiles();
}
},
//文件上传之前钩子
beforeAvatarUpload(file) {
window.console.log(file.name.split(".")[file.name.split(".").length - 1]);
// 限制文件格式类型
// const isDocx = file.name.split('.')[1] === 'docx'
const flag = this.restrictFileTypes.some((item) => {
return file.name.split(".")[file.name.split(".").length - 1] === item;
});
if (!flag && this.restrictFileTypes.length !== 0) {
this.$message({
message: "请上传指定类型的文件!",
type: "error",
});
// this.$forceUpdate();
return false;
}
// 限制文件上传大小
const isLt10M = file.size / 1024 / 1024 < 128;
if (!isLt10M) {
this.$message.error("上传文件大小不能超过 128MB!");
// this.$forceUpdate();
return false;
}
},
handleChange(file, fileList) {
this.fileList = fileList.slice(-1);
},
// 提交表单
submit() {
if(this.fileList.length !== 0) {
this.$emit('submit', this.in_Params)
} else {
this.$message.warning('请先导入对应模板的数据文件!')
}
},
tableFileSubmit() {
let prop = this.columnArray.find(item => item.type == 'uploadFile').prop
this.tableData.forEach(item => {
if(item[this.rowFileIdName] == this.tableFileParams.data[this.uploadFileIdName]) {
// window.console.log(item.id, this.tableFileParams.data[this.uploadFileIdName])
item[prop] = JSON.parse(JSON.stringify(this.tableFileParams.fileTable))
}
})
this.$nextTick(() => {
this.closeFileDialog()
});
},
handleClick(type, item, index) {
// window.console.log(type);
if (type === "remove") {
this.$confirm("此操作将清空批量导入的文件及列表数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
this.fileList.splice(index, 1);
this.initData()
})
} else if(type === "down") {
if(this.outSideDownFn) {
this.$parent[this.outSideDownFn]()
} else {
window.location.href = `${API_PATH}/dictionary/template?exportMark=${this.exportMark}`;
}
}
},
// 删除附件内容
deleteFile(row) {
this.$confirm("此操作将删除该附件, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
this[this.fileDeleteApi]({ fileId: row.fileId }).then(() => {
this.tableFileParams.fileTable.splice(this.tableFileParams.fileTable.indexOf(row), 1)
this.$message.success('删除成功!')
// 删除后同步到列表中
this.$nextTick(() => {
let prop = this.columnArray.find(item => item.type == 'uploadFile').prop
this.tableData.forEach(item => {
if(item[this.rowFileIdName] == this.tableFileParams.data[this.uploadFileIdName]) {
item[prop] = JSON.parse(JSON.stringify(this.tableFileParams.fileTable))
}
})
});
}).finally(() => {})
})
},
//文件上传成功钩子
handleAvatarSuccess_table(res) {
window.console.log(res)
if (res.success){
this.$message.success('上传成功');
this.getFileList(res.data)
this.tableFileParams.fileList = [];
setTimeout(() => {
this.$refs.uploaddemo_table.clearFiles();
}, 1000);
} else {
this.$message.warning(res.code === '400' || res.code === '500' ? res.message : '上传失败,请重试!');
this.$refs.uploaddemo_table.clearFiles();
}
},
// 附件表格
getFileList(files) {
this.tableFileParams.fileTableLoading = true;
this.tableFileParams.fileTable.push(...files);
setTimeout(() => {
this.tableFileParams.fileTableLoading = false;
}, 1000)
},
//文件上传之前钩子
beforeAvatarUpload_table() {
return true
},
handleChange_table(file, fileList) {
this.tableFileParams.fileList = fileList.slice(-1);
},
handleSizeChange(val) {
// window.console.log(`每页 ${val} 条`);
this.params.size = val;
this.initTable();
},
handleCurrentChange(val) {
// window.console.log(`当前页: ${val}`);
this.params.current = val;
this.initTable();
},
handleExceed() {
this.$message.warning(`选择上传文件超出限制!`);
},
// 附件上传弹窗关闭
closeFileDialog() {
this.innerVisible = false
this.tableFileParams.data = {}
this.tableFileParams.fileTable = []
},
initTable(inParams = {}) {
this.in_Params = {...inParams, ...this.in_Params}
if(!this.tableApi) {
this.$message.warning(`请先配置对应的列表请求API!`);
return
}
this.tableLoading = true
this[this.tableApi]({
...this.params,
...this.in_Params
}).then(res => {
this.tableData = res.rows
this.params.total = res.records
this.importData = this.importData === 0 ? res.records : this.importData
}).finally(() => {
this.tableLoading = false
})
},
},
};
script>
<style lang="scss">
.table_file {
line-height: 20px;
cursor: pointer;
color: #333;
transition: all 0.3s;
&:hover {
color: #66b9ff;
}
}
.fileTitle {
display: block;
width: 100%!important;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
// popover 弹窗样式 浅色
.popoverClass_light {
min-width: 176px;
max-width: calc(30vw + 24px);
// max-height: calc(25vh + 24px);
.el-popover__title {
font-family: MicrosoftYaHei-Bold;
font-size: 12.5px;
color: #666;
font-weight: 700;
}
.tableFile {
display: flex;
justify-content: space-between;
padding-left: 5px;
transition: all 0.3s;
.name {
width: 240px;
// max-width: 800px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #666;
&:hover {
color: #66b9ff;
}
}
.btn {
display: flex;
justify-content: space-around;
align-items: center;
width: 60px;
font-size: 16px;
font-weight: bold;
color: #b8c9e6;
}
}
}
style>
<style scoped lang="scss">
.fileUpload {
/deep/ {
// 修改分页组件样式
.el-pagination {
margin-top: 20px;
text-align: center;
color: #fff;
.btn-next,
.btn-prev,
.el-pager li,
.el-select .el-input .el-input__inner,
.el-pagination__editor.el-input .el-input__inner {
background: rgba(67, 137, 249, 0.06);
color: #333333;
border: 0px solid #2a5cb0;
border-radius: 4px;
}
.el-pager li:not(.disabled).active {
background-color: #4389f9;
}
.el-pagination__jump,
.el-pagination__total {
color: #545454;
margin-left: 10px;
}
}
.line {
height: 1px;
margin: 15px 15px 0;
// background: #ccc;
border-bottom: 1px solid #d9d9d9;
}
.el-dialog__wrapper {
// background-color: rgba(0,0,0,0.4)
}
.uploadFiles {
width: 650px!important;
height: auto!important;
margin-top: calc(50vh - 150px)!important;
.el-dialog__header {
border-bottom: 1px solid #4389f9 !important;
height: 48px !important;
.el-dialog__headerbtn {
font-family: MicrosoftYaHei-Bold;
font-size: 16px !important;
color: #ffffff !important;
line-height: 30px;
font-weight: 700;
}
}
.el-dialog__body {
padding: 15px!important;
height: 250px;
overflow-y: auto;
}
}
/*修改添加模型弹窗 */
.el-dialog {
width: 994px;
height: 540px;
background: #1f2c4d !important;
border: 1px solid #4389f9;
border-radius: 4px;
.el-dialog__header {
border-bottom: 1px solid #4389f9 !important;
height: 48px !important;
.bda-dialog-header .bda-dialog-header-title {
font-family: MicrosoftYaHei-Bold;
font-size: 16px !important;
color: #ffffff !important;
line-height: 48px;
font-weight: 700;
}
}
.bda-dialog-body-main {
height: 438px !important;
.el-form {
.el-row:nth-of-type(3) {
height: 80px;
.el-textarea__inner {
height: 60px;
background: #041338;
border: 1px solid #4389f9;
color: #4298f3;
&::placeholder {
font-family: MicrosoftYaHei;
font-size: 14px;
color: #4298f3;
font-weight: 400;
}
}
}
.el-row:nth-of-type(4) {
height: 110px;
.el-textarea__inner {
height: 90px;
background: #041338;
border: 1px solid #4389f9;
color: #4298f3;
&::placeholder {
font-family: MicrosoftYaHei;
font-size: 14px;
color: #4298f3;
font-weight: 400;
}
}
}
}
}
.el-dialog__footer {
border-top: 1px solid #4389f9 !important;
height: 52px !important;
.dialog-footer {
display: block;
height: 100%;
padding: 11px 20px;
box-sizing: border-box;
}
}
}
/*修改表格单元格高度*/
.bda-pagination-table {
.bda-pagination-table-page {
border: 0 !important;
height: 50px !important;
}
.bda-pagination-table-main {
height: calc(100% - 40px);
}
} /*解决调整单元格高度后,fixed错位*/
.el-table__fixed-body-wrapper {
top: 37px !important;
}
/*解决表格滚动高度固定导致的异常*/
.el-table__body-wrapper.is-scrolling-left {
height: calc(100% - 48px) !important;
}
.el-table__body-wrapper.is-scrolling-right {
height: calc(100% - 48px) !important;
}
.el-table__body-wrapper.is-scrolling-middle {
height: calc(100% - 48px) !important;
}
.el-table__fixed-body-wrapper {
height: calc(100% - 34px) !important;
}
/*解决调整列宽度时,出现列内容未完整显示的异常*/
.el-table .cell.el-tooltip {
width: 100% !important;
}
.el-table__header-wrapper {
background-color: #fff !important;
}
.el-table__body-wrapper {
background-color: #fff !important;
}
.el-table__header th {
// background-color: #22519c !important;
background: #e9f1fe !important;
height: 48px;
border-color: #bbb;
.cell {
color: #666 !important;
text-align: center;
}
}
.bda-table-main {
background-color: #ffffff;
}
.bda-main {
/*height: calc(100% - 52px);*/
border: 1px solid #bbb;
.el-table__row {
&:hover > td {
background-color: #ebfcff !important;
}
> td {
height: 48px;
border-color: #bbb;
.cell {
color: #333;
text-align: center;
.el-button {
color: #66b9ff;
}
}
}
> td:nth-last-child(3) {
.cell {
/*color: red;*/
text-align: center;
}
}
}
.el-table__row:nth-of-type(odd) {
background-color: #fff;
}
.el-table__row:nth-of-type(even) {
background-color: #fff;
}
.bda-table {
.bda-table-scroll_x {
height: 8px !important;
}
.bda-table-scroll_x_view {
height: 8px !important;
background-color: #b0b1b2 !important;
}
}
}
}
.title {
text-align: left!important;
}
.upload-box {
display: flex;
.text {
margin-left: 10px;
}
}
h2 {
font-size: 16px;
color: #333333;
font-weight: 700;
}
.dialogBox {
padding-bottom: 15px;
.tableHeader_1 {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
.name {
font-size: 14px;
font-weight: bold;
color: #333;
}
/deep/ {
.el-radio-group {
/* // border: 1px solid #4389F9 ; */
margin: 0 -1px;
border-radius: 5px;
.el-radio-button {
margin-bottom: 5px;
.el-radio-button__inner {
border: 1px solid #4389F9;
margin-right: -1px;
}
&:first-child {
.el-radio-button__inner {
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
}
&:last-child {
.el-radio-button__inner {
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
}
}
}
.el-radio-button:not(.is-active) {
.el-radio-button__inner {
color: #333;
border-color: #4389f9;
background-color: rgba($color: #fff, $alpha: 1);
}
}
.el-radio-button.is-active {
.el-radio-button__inner {
border-color: #4389f9;
background-color: rgba($color: #4389f9, $alpha: 1);
color: #fff;
}
}
}
}
}
}
}
.fileUpload_light {
/deep/ {
.el-dialog {
background: #ffffff !important;
border: 1px solid #c2ddff;
border-radius: 4px;
.el-dialog__header {
border-bottom: 1px solid #cccccc !important;
height: 48px !important;
.bda-dialog-header .bda-dialog-header-title {
font-family: MicrosoftYaHei-Bold;
font-size: 16px !important;
color: #333333 !important;
line-height: 48px;
font-weight: 700;
}
}
.el-dialog__footer {
border-top: 1px solid #cccccc !important;
height: 52px !important;
.dialog-footer {
display: block;
height: 100%;
padding: 11px 20px;
box-sizing: border-box;
}
}
}
}
}
style>
案例较为粗浅,仅供参考!
在开发过程中,测试提及的一个需求:列表附件上传要求能够多选,但是单独新增对应的elementUi 上传组件的 multiple
属性,并不能实现多选。组件报了个 上传状态错位的问题!如下图所示:
原因:查询资料得知,这是由于多个文件上传,我们又在文件上传成功后,对存储file的fileList
文件进行了变动(删除
),导致组件内部逻辑无法查询到上传的对应文件的file值
, 从而诱使后续的取值为null报错!
解决方案如下,增加判断逻辑,延长定时器定时清理时间!change方法避免截取掉多选上传的附件内容!
//文件上传成功钩子
handleAvatarSuccess_table(res) {
window.console.log(res)
if (res.success){
this.$message.success('上传成功');
this.getFileList(res.data)
if(this.isMultiple){
setTimeout(() => {
this.tableFileParams.fileList = [];
this.$refs.uploaddemo_table.clearFiles();
}, 2500);
} else {
this.tableFileParams.fileList = [];
setTimeout(() => {
this.$refs.uploaddemo_table.clearFiles();
}, 1000);
}
} else {
this.$message.warning(res.code === '400' || res.code === '500' ? res.message : '上传失败,请重试!');
this.$refs.uploaddemo_table.clearFiles();
}
},
// 附件状态变更
handleChange_table(file, fileList) {
window.console.log(file,fileList)
if(!this.isMultiple){
this.tableFileParams.fileList = fileList.slice(-1);
} else {
this.tableFileParams.fileList = fileList;
}
},
< 每日小技巧: 基于Vue状态的过渡动画 - Transition 和 TransitionGroup>
< 每日份知识快餐:axios是什么?如何在Vue中 封装 axios ? >
< 在Vue中 el-popover + el-tiptap 实现 富文本框输入,表格点击展示 (富文本HTML标签渲染) >
< 知识拓展:CSS 中常用的计量单位有哪些? >