vue 2.5.2 、 element-ui 2.13.0
html
<table v-for="(industryForm,index) in simulationTableArr" :key="index" cellspacing="0" cellpadding="0" class="simulationTable">
<tr>
<td :rowspan="industryForm.industryArr.length+1" style="width: 200px">{{industryForm.title}}td>
<td style="height:0;border:0;width: 400px">td>
<td :rowspan="industryForm.industryArr.length+1" class="table-upload">
<fileUpload :fileUrl.sync="formData[industryForm.formFileName]">
<i class="industry-upload-icon">i>上传
fileUpload>
td>
tr>
<tr v-for="(item,index2) in industryForm.industryArr" :key="'item'+index2">
<td>
<i class="industry-icon">i><span>{{item.name}}span>
<div @click="downTemp(item.downUrl)" class="industry-down">
<i class="industry-down-icon">i><span>下载模板span>
div>
td>
tr>
table>
js
showSimulation(value) {
const temp = [STRUCTURE_SIMULATION, ELECTROMAGNETIC_SIMULATION, HOT_SIMULATION, FLUID_SIMULATION];
let arr = [];
value.forEach(e => {
arr.push(temp[e]);
});
this.simulationTableArr = arr;
},
组件内部
<template>
<el-upload class="file-upload-display"
:action="fileUploadUrl"
:headers="headers"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="handleSuccess"
:on-change="handleChange"
:file-list="initialFile">
<slot></slot>
</el-upload>
</template>
<script>
import {createProjectUploadUrl} from "@/server/config"
export default {
name: "fileUpload",
data() {
return {
headers: {
"Authorization": "JWT " + this.$store.getters.token
},
fileUploadUrl: createProjectUploadUrl,
initialFile: [],
}
},
props: {
fileUrl: {
type: String,
default: ''
},
limitSize: {
type: Number,
default: 50
}
},
methods: {
beforeUpload(file) {
const isOverSize = file.size / 1024 / 1024 > this.limitSize;
if (isOverSize) {
this.error(`上传文件不能超过${this.limitSize}MB!`);
return false
}
},
handleRemove(file, fileList) {
this.$emit('update:fileUrl', '');
},
handleSuccess(file, fileList) {
console.log(file);
this.$emit('update:fileUrl', file.data);
},
handleChange(file, fileList) {
this.initialFile = fileList.slice(-1);
}
},
watch:{
'fileUrl':{
handler:function (val,oldVal) {
if (val) {
this.initialFile = [
{
url: val,
name: val.slice(val.lastIndexOf('/') + 1, val.lastIndexOf('_')) + val.slice(val.lastIndexOf('.'))
}
]
} else {
this.initialFile = []
}
},
immediate:true
}
}
}
</script>
思路就是将v-for的复用策略干掉。经过一系列尝试,最终方案。先将数据清空,等dom挂载上去的时候,再赋值数据渲染。东西都没了,看你怎么复用2333。
showSimulation(value) {
const temp = [STRUCTURE_SIMULATION, ELECTROMAGNETIC_SIMULATION, HOT_SIMULATION, FLUID_SIMULATION];
let arr = [];
value.forEach(e => {
arr.push(temp[e]);
});
this.simulationTableArr = [];
this.$nextTick(() => {
this.simulationTableArr = arr;
});
},
在充分了解v-for关于diff的算法后,我知道我错了。:key值不能轻易的用index来使用,v-for只要涉及到列表的变动,特别是删除和更换顺序等,绝对不能用index。因此改成如下即可解决,不需要那么大费周折
html
<table v-for="(industryForm,index) in simulationTableArr" :key="industryForm.id" cellspacing="0" cellpadding="0" class="simulationTable">
<tr>
<td :rowspan="industryForm.industryArr.length+1" style="width: 200px">{{industryForm.title}}td>
<td style="height:0;border:0;width: 400px">td>
<td :rowspan="industryForm.industryArr.length+1" class="table-upload">
<fileUpload :fileUrl.sync="formData[industryForm.formFileName]">
<i class="industry-upload-icon">i>上传
fileUpload>
td>
tr>
<tr v-for="(item,index2) in industryForm.industryArr" :key="'item'+index2">
<td>
<i class="industry-icon">i><span>{{item.name}}span>
<div @click="downTemp(item.downUrl)" class="industry-down">
<i class="industry-down-icon">i><span>下载模板span>
div>
td>
tr>
table>