vue项目动态表格渲染,表格编辑,上传文件,多个table表格展示等(具体见代码)分享给有需要的家人们
页面代码
template
<template>
<div>
<el-header style="height:50px">
<el-row :gutter="10">
<el-row
type="flex"
class="row-bg"
justify="space-between"
>
<el-col :span="6"></el-col>
<el-col :span="6" style="text-align: right"><el-button type="success" icon="el-icon-circle-check" @click="save">保 存</el-button></el-col>
</el-row>
</el-row>
</el-header>
<el-tabs v-model="activeName" type="border-card" @tab-click="tabsClick">
<!-- 动态tabs 渲染 -->
<el-tab-pane
:key="item.id"
v-for="(item, index) in editableTabs"
:label="item.lable"
:name="item.name"
>
<el-form :model="ruleForm.tbody" >
<!-- ruleForm因为会有多个表格,ruleForm是一个数组,里面每个对象对应的是一个独立的table数据-->
<div
v-for="(item1, index) in ruleForm"
:key="index"
style="margin-bottom: 30px"
>
<!-- 分类标题 -->
<p style="margin: 0;
line-height: 35px;
background: rgba(223, 223, 223,0.3);
border-radius: 6px 6px 0 0;
font-weight: 700;
text-align:center;
color: #888;">{{item1.stutas.name}}</p>
<!-- 动态table表格 渲染 -->
<!-- thead是表格的表头数据,,thead是一个数组,里面每个对象对应的是表头数据-->
<!-- tbody是表格的单元格数据,这里把所有数据放在一起(一个对象中),类似vue的双向数据绑定,这样方便提交form表单,避免多个表单逐个提交 -->
<el-table
:data="item1.tbody"
stripe
border
style="width: 100%"
size="mini"
>
<div v-for="(item2, i) in item1.thead" :key="i" >
<!-- 动态表头渲染 -->
<el-table-column :label="item2.annotationFields" min-width="250" align="center">
<template slot-scope="scope">
<!-- 动态单元格数据渲染 -->
<el-form-item :prop="item2.fieldName" >
<!-- 根据表头data数据类型不同,在页面中展示不同控件,也可以做是否必填项的表单验证 -->
<!-- 考虑到数据类型可能是下拉框格式,这里就需要动态获取下拉框数据 -->
<!-- 因为动态数据原因item2.fieldName是动态,这里使用作用域插槽就需要注意 可写scope.row[item2.fieldName] -->
<el-select
:ref="item2.fieldName"
v-if="item2.data == 1"
@visible-change="visibleChange($event,item2.annotationFields, item2.fieldName)"
v-model="scope.row[item2.fieldName]"
placeholder="请选择">
<el-option
v-for="(item, index) in options"
:key="index"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<!-- 数据类型可能是上传图片的情况,简单封装elementUI 的上传文件控件-->
<!-- <div class="block" v-else-if="item2.data == 2">
<uploadFileByPicture :fieldName="item2.fieldName" :srcList="change(scope.row[item2.fieldName])" @uploadFile="uploadFile"></uploadFileByPicture>
</div> -->
<div class="block" v-else-if="item2.data == 3">
<el-input
type="textarea"
:rows="2"
v-model="scope.row[item2.fieldName]">
</el-input>
<el-input type="file" v-model="scope.row[item2.fieldName]" ></el-input>
</div>
<div class="block" v-else-if="item2.data ==4">
<el-input
type="textarea"
:rows="2"
v-model="scope.row[item2.fieldName]">
</el-input>
<el-input type="file" v-model="scope.row[item2.fieldName]" ></el-input>
</div>
<el-select
v-else-if="item2.data == 6"
v-model="scope.row[item2.fieldName]"
placeholder="请选择">
</el-select>
<el-input
v-else
v-model="scope.row[item2.fieldName]"
:disabled="item2.fieldName == 'Code_credit' || item2.fieldName == 'Code_org' ? true : false"
clearable
></el-input>
<!-- <el-tag>{{split(scope.row,item2.porp)}}</el-tag> -->
</el-form-item>
</template>
</el-table-column>
</div>
</el-table>
</div>
</el-form>
</el-tab-pane>
</el-tabs>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="">
</el-dialog>
</div>
</template>
data
data() {
return {
ip:"http://192.168.3.80:9090/static/",
activeName: '任务一',
clickTabsName:"",
videoFlag: false,
dialogVisible: false,
tableHeight: null,
//是否显示进度条
videoUploadPercent: "",
//进度条的进度,
isShowUploadVideo: false,
selectObj: { companypolicy_tzvoc: [] },
//显示上传按钮
videoForm: {
showVideoPath: ''
},
dialogImageUrl: '',
ruleForm:[
{
stutas: {
id: 5868,
name: "基本信息",
}, //分类
thead: [
{
annotationFields: "单位详细名称",
fieldName: "Code_credit",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2032,
data:1,
isNull: "DEFAULT NULL",
},
{
annotationFields: "大师傅范德萨",
fieldName: "Contact_name",
fieldType: "varchar(32)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2033,
data:1,
isNull: "NULL",
},
{
annotationFields: "组织机构代码",
fieldName: "Code_org",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2034,
data:1,
isNull: "DEFAULT NULL",
},
{
annotationFields: "手机号",
fieldName: "Contact_phone",
fieldType: "varchar(32)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2035,
isNull: "DEFAULT NULL"
},
{
annotationFields: "单位地址",
fieldName: "District",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2032,
isNull: "DEFAULT NULL",
}
,
{
annotationFields: "单位地址",
fieldName: "District",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2032,
isNull: "DEFAULT NULL",
},
],
tbody: [
{
Boil_turb_YN: "1",
City: "安庆市",
Clinker_YN: "否",
Code_credit: "913408227049401051()",
Code_org: "704940105()",
Coking_YN: "否",
Contact_name: "吴邵明",
Contact_phone: "13805564798",
District: "怀宁县",
},
],
},
{
stutas: {
id: 15868,
name: "特殊信息",
}, //分类
thead: [
{
annotationFields: "单位详细名称",
fieldName: "Code_credit",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2032,
isNull: "DEFAULT NULL",
},
{
annotationFields: "大师傅范德萨",
fieldName: "Contact_name",
fieldType: "varchar(32)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2033,
isNull: "NULL",
},
{
annotationFields: "组织机构代码",
fieldName: "Code_org",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2034,
isNull: "DEFAULT NULL",
},
{
annotationFields: "手机号",
fieldName: "Contact_phone",
fieldType: "varchar(32)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2035,
isNull: "DEFAULT NULL"
},
{
annotationFields: "单位地址",
fieldName: "District",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2032,
isNull: "DEFAULT NULL",
}
,
{
annotationFields: "单位地址",
fieldName: "District",
fieldType: "varchar(128)",
fieldTypeId: "18",
fieldTypeName: "企业基本信息",
id: 2032,
isNull: "DEFAULT NULL",
},
],
tbody: [
{
Boil_turb_YN: "1",
City: "安庆市",
Clinker_YN: "否",
Code_credit: "913408227049401051()",
Code_org: "704940105()",
Coking_YN: "否",
Contact_name: "吴邵明",
Contact_phone: "13805564798",
District: "怀宁县",
},
],
},
],
editableTabs: [
{
name: '任务一',
lable: '任务一',
id: 0,
},
{
name: '任务二',
lable: '任务二',
id: 1,
},
{
name: '任务三',
lable: '任务三',
id: 2,
}
],
// editableTabs: [
// {
// name:"数据加载中...",
// id:0
// }
// ],
rules: {
Code_credit: [
{ required: true, message: "统一社会信用代码", trigger: "blur" },
],
},
removeSealDescriptionIdArray: [], //要删除的table每一行 的SealDescriptionId数组
tabID:0,
urlData:{},
dataId:'',
options:''
};
},
methods
methods: {
//tab且切换
tabsClick(tab, event) {
this.activeName = tab.name
this.tabID = tab.index
this.clear()
this.getParams(tab.index)
// this.clickTabsName = tab.name
// this.getParams(tab.name)
},
//获取下拉框数据
visibleChange(flag,label, fieldName) {
this.options=''
if (!flag || this.selectObj[fieldName].length != 0) {
return false;
}
//this.$refs[fieldName][0].placeholder = "加载中";
let params = {
dictionaryName: label,
};
this.axios
.post("/dictionaryInfo/queryDictonary", params)
.then(({ data: res }) => {
console.log(res,222);
if (res.data.list.length != 0) {
if (res.data.list[0].children.length != 0) {
let array = res.data.list[0].children;
let resultList = [];
for (let index = 0; index < array.length; index++) {
let item = array[index];
resultList.push({
label: item.dictionaryName,
value: item.dictionaryName,
});
}
//this.$refs[fieldName][0].placeholder = "请选择";
this.options = resultList;
} else {
//this.$refs[fieldName][0].placeholder = "不存在下拉数据";
this.$notify({
title: "警告",
message: "不存在下拉数据",
type: "warning",
duration: 1500,
position: "bottom-right",
});
}
} else {
//this.$refs[fieldName][0].placeholder = "不存在下拉数据";
this.$notify({
title: "警告",
message: "不存在下拉数据",
type: "warning",
duration: 1500,
position: "bottom-right",
});
}
});
this.$forceUpdate();
},
uploadFile(val){
console.log(val.fieldName,val.list);
this.urlData[val.fieldName] = val.list.toString()
},
change(e) {
if (e) {
return e.split(',')
}else{
return []
}
},
split(row, item) {
let value;
Object.keys(row).forEach((v) => {
if (item == v) {
value = row[v];
// console.log(row[v]);
}
});
return value;
},
delSealRow(a, b) {
console.log(a, b);
},
handleChange(file){
console.log(file);
},
handleRemove(file) {
//console.log(file);
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleDownload(file) {
///console.log(file);
},
handlePreview(file) {
},
beforeRemove(file) {
},
handleExceed(file) {
},
//sp上传前回调
beforeUploadVideo(file) {
var fileSize = file.size / 1024 / 1024 < 50;
if (['video/mp4', 'video/ogg', 'video/flv', 'video/avi', 'video/wmv', 'video/rmvb', 'video/mov'].indexOf(file.type) == -1) {
layer.msg("请上传正确的视频格式");
return false;
}
if (!fileSize) {
layer.msg("视频大小不能超过50MB");
return false;
}
this.isShowUploadVideo = false;
},
//进度条
uploadVideoProcess(event, file) {
this.videoFlag = true;
this.videoUploadPercent = file.percentage.toFixed(0) * 1;
},
//上传成功回调
handleVideoSuccess(res, file) {
this.isShowUploadVideo = true;
this.videoFlag = false;
this.videoUploadPercent = 0;
//前台上传地址
//if (file.status == 'success' ) {
// this.videoForm.showVideoPath = file.url;
//} else {
// layer.msg("上传失败,请重新上传");
//}
//后台上传地址
if (res.Code == 0) {
this.videoForm.showVideoPath = res.Data;
} else {
layer.msg(res.Message);
}
},
},
提示
这里数据是假数据,工作中需要调接口拿数据,家人们把数据处理一下就可以了,直接methods不用写 也能通过假数据实现动态的效果,methods里面的方法在实际项目中可能需要的,仅供参考,如有其他需求疑问欢迎留言讨论