項目需求:
- 可上傳多個文件
- 可刪除
- 文件過大時用戶輸入可上傳至其他網站,並將文件名和地址上傳至本網站
問題點:
- 大文件用戶輸入內容無法合並到已上傳文件的列表進行展示
- 上傳多個大文件地址時前面已上傳的大文件會被改變
- 無法取消彈窗的代碼校驗
原因和解決方案
- 大文件信息填寫的之后可以將內容push到fileList, 並將值賦值給對應字段
- 將對象push到數組, 是淺拷貝, 再次對對象進行賦值時, 數組中push的元素會被改變,
需要將淺拷貝改為深拷貝, 例如: push(JSON.parse(JSON.stringify(this.form)))
- 我原本是想在彈窗出現時取消校驗, 但是此時彈窗的DOM還未創建完成(可能是這個原因), 無法獲取Dom, 會報錯.
可以在點擊彈窗的確定, 數據校驗成功之后取消校驗
所有原因及解決方案都在代碼中有備注
element組件代碼
<el-upload
class="upload-demo"
:action="actionUrl"
:on-success="handleAvatarSuccess2"
:before-upload="beforeAvatarUpload2"
multiple
:limit="5"
:on-exceed="handleExceed"
:before-remove="beforeRemove"
:on-remove="handleRemove"
:file-list="fileList"
>
<el-button size="small" type="primary">點擊上傳</el-button>
<div slot="tip" class="el-upload__tip">
<!-- <p v-for="(itm, idx) of formDate.appendixSaveRequests" :key="idx">{{ itm.fileName }}</p>-->
</div>
</el-upload>
<!-- 上傳大文件附件時的彈窗-->
<el-dialog title="提示" :visible.sync="dialogFormVisible">
<p class="i-info">
<!-- <i class="el-icon-warning"></i>-->
如果您需要上傳的附件過大,可上傳至網盤,在此留下網盤地址</p>
<el-form :model="form" :rules="formRule" ref="form">
<el-form-item label="附件名稱" prop="fileName" :label-width="formLabelWidth">
<el-input v-model="form.fileName" placeholder="請輸入附件名稱" autocomplete="off" />
</el-form-item>
<el-form-item label="附件地址" prop="fileUrl" :label-width="formLabelWidth">
<el-input v-model="form.fileUrl" placeholder="例:http://***.com" autocomplete="off" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="addBigFile">確 定</el-button>
</div>
</el-dialog>
// js部分
data () {
return {
dialogFormVisible: false,
form: { // 大文件輸入的名稱和地址
fileName: '',
fileUrl: '',
},
fileList: [],
}
},
methods: {
// 添加大文件
addBigFile() {
this.$refs.form.validate(valid => {
// 驗證fileUrl地址和必填項非恐校驗
var strRegex = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/|www\.)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~\/])+$/;
var re=new RegExp(strRegex);
if (valid && re.test(this.form.fileUrl)) {
this.dialogFormVisible = false
this.form.name = this.form.fileName
// this.form和this.fileList里的item都為對象類型, push相當於淺拷貝, 再次添加時this.form的值改變, 導致this.fileList里的值重復, 所以需要用深拷貝代替淺拷貝
let form = JSON.parse(JSON.stringify(this.form))
// 點擊彈窗的確定時將彈窗中的內容push到fileList, 注意: push的字段名稱要和fileList原本的字段名稱一致
this.fileList.push(form)
this.resetForm('form')
} else {
this.$message.error('請輸入正確的附件地址')
}
})
},
// 上傳之前
beforeAvatarUpload2(file) {
const sizeFlag = file.size / 1024 / 1024 < 10
if (!sizeFlag) {
console.log(this.fileList, '=======')
this.dialogFormVisible = true
this.form.fileName = ''
this.form.fileUrl = ''
this.form.isThirdpartyStorage = true
}
return sizeFlag
},
// 上傳成功
handleAvatarSuccess2(res, row) {
// console.log(res, row)
if (res.code === 0) {
// 下面為項目中上傳附件的字段, 可忽略
this.formDate.appendixSaveRequests.push({
fileName: row.name,
name: row.name,
fileUrl: res.data.url,
isThirdpartyStorage: false
})
}
},
// 已刪除
handleRemove(file, fileList) {
console.log('this.fileList=111111==')
// 編輯頁面刪除時要將后端返回的對應的字段內容刪除
this.formDate.appendixSaveRequests.map((item, index) => {
if(item.uid === file.uid) {
this.formDate.appendixSaveRequests.splice(index, 1)
}
})
},
// 達到限制數量
handleExceed(files, fileList) {
this.$message.warning(`當前限制選擇 5 個文件,本次選擇了 ${files.length} 個文件`)
},
// 刪除之前
beforeRemove(file, fileList) {
// return this.$confirm(`確定移除 ${file.name}?`)
}
}