element ui提供了成熟的組件場景,但實際工作中難免會遇到認(sha)真(diao)的產品。比如,最近遇到的,要求實現手動上傳特定格式文件(用戶點擊“上傳文件”按鈕,確定之后,只是單純選擇了文件,點擊頁面上的“提交”按鈕才上傳),並展示用戶選擇的文件名稱,且只能選擇一個文件,如果用戶選擇第2,3,4...等文件,要求后者覆蓋前者,即用戶看到的總是最新選擇的文件。
OK,需求合理,但是,查了查API,呃。。。貌似不太好完美實現。
查源碼,改樣式。完美奉上解決方案。
一,實際應用場景
實現手動上傳特定格式的文件,展示所選文件名稱,且能實現覆蓋上傳。
二,分析
1, 解決手動上傳問題
官網API(https://element.eleme.cn/#/zh-CN/component/upload),給出“手動上傳”,只需要在Upload組件添加 屬性 :auto-upload="false" ,然后調用 this.$refs.upload.submit(); 方法即可。
2,解決特定格式文件問題
這塊,也有例子,對於本項目,要求添加csv格式, 所以,Upload組件添加 屬性 accept=".csv"
3,最麻煩的是上傳限制問題
首先想到官網API里的 limit屬性, Upload組件添加屬性 :limit="1",但是這樣,無聊怎么選擇文件,頁面上展示的始終是第一次選擇的文件,這效果和我想的大相徑庭。
“單身限制了你的想象力”
繼續翻,看到file-list屬性,保存的是用戶選擇的文件數組。
想通過on-change方法,改變file-list里選擇的文件列表,只保留最后一項。邏輯上來說行得通。
代碼如下:
模板代碼(已精簡):
<template> <div> <el-upload class="upload-demo" ref="upload" // 注意1 accept=".csv" // 注意2 :file-list="fileList" // 注意3 :on-change="handleChange" // 注意4 :action="uploadUrl" :show-file-list="true" :on-success="onSuccess" :on-error="onError" :auto-upload="false" // 注意5 > <el-button type="primary" slot="trigger">選取文件</el-button> </el-upload> <el-button type="primary" @click="handleSubmit">提交</el-button> </div> </template>
script代碼:
<script> export default { name: 'Upload', data() { fileList: [], uploadUrl: '', }, methods: { onSuccess(res) { this.$alert(res.data, '提示', { confirmButtonText: '確定', callback: action => { console.log("上傳成功") }, }) }, onError(res) { this.$alert('創建失敗', '提示', { confirmButtonText: '確定', callback: action => { console.log("上傳失敗") }, }) }, handleChange(file, fileList) { if (fileList.length > 0) { this.form.fileList = [fileList[fileList.length - 1]] // 這一步,是 展示最后一次選擇的csv文件 } }, submit() {
this.uploadUrl = '/upload' // 這里,讀者換成實際項目中的上傳接口 this.$nextTick(() => { this.$refs.upload.submit() }) }, }, } </script>
到這里,基本功能上實現了目標場景,但是有一個樣式問題,因為是認為改變file-list,取最后一項,因此,用戶選擇第二個文件后,從第一個文件到第二個文件,有動態切換的效果,這不是我想要的,我想要的是 用戶點擊“上傳文件”,本地電腦 選擇文件,點擊“確定”,頁面上直接展示所選文件,不要動態切換。
鼓搗很久(省略很多字),翻看element upload組件的css源碼。
去掉這一部分動畫,完美解決。
css代碼如下:
<style lang="scss" scoped> .upload-demo { display: flex; } /deep/ .el-list-enter-active, /deep/ .el-list-leave-active { transition: none; } /deep/ .el-list-enter, /deep/ .el-list-leave-active { opacity: 0; } /deep/ .el-upload-list { height: 40px; } </style>
至於css中的 /deep/ 是干嘛的,其實是修改elementui等第三方組件內部樣式,做的滲透。如果不用scss, 可以使用 >>> 符號來修改第三方組件內部樣式。
三,總結
“什么都不懂的時候,我曾擁有全部。”
本文思路,從 踩過的坑 到解決問題,耗時許久,如需轉載,請標明出處,感謝配合。
還是同樣的ps,每次用element ui 都會有一些感觸,
苦笑。