Commit 116d2ab72cb69a1993bad957a3e8cb603f28ff14

Authored by 刘汉宸
1 parent 11a65483

feat: 优化Upload组件

examples/views/docs/component/upload.md
... ... @@ -4,14 +4,55 @@
4 4  
5 5 ## 基础用法
6 6  
7   -默认为图片上传
  7 +默认支持图片和图片一起上传
8 8  
9   -::: snippet 图片上传
  9 +::: snippet 配置项`action`、`headers`、`data`与**Element**中的**el-upload**相同,值的格式为逗号分隔的字符串
  10 +
  11 +```html
  12 +<template>
  13 + <z-upload v-model="model" action="http://47.98.245.217:7070/tms-web-api/upload/image" :headers="headers" :data="uploadData"></z-upload>
  14 +</template>
  15 +
  16 +<script>
  17 +export default {
  18 + data() {
  19 + return {
  20 + model: 'https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/null/3a3d0bb1-a5eb-4957-aa7a-54d004769be6.png,https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/null/a1a7e2fe-5896-44ed-9935-549050e9444c.png',
  21 + headers: {
  22 + 'Authorization': 'Bearer 2a6238c6-5a87-4f3f-893b-14aef14b9539'
  23 + },
  24 + uploadData: {
  25 + module: 'tms'
  26 + }
  27 + }
  28 + },
  29 +}
  30 +</script>
  31 +```
  32 +
  33 +:::
  34 +
  35 +## 限制上传
  36 +
  37 +可以限制图片上传或者文件上传
  38 +
  39 +::: snippet `type`设置上传模式,`limit`限制上传数量,`file-type`限制文件上传格式
10 40  
11 41 ```html
12 42 <template>
13 43 <div>
14   - <z-upload v-model="model"></z-upload>
  44 + <div>
  45 + <div>文件上传:</div>
  46 + <z-upload v-model="file" type="file" action="http://47.98.245.217:7070/tms-web-api/upload/image" :limit="1" :headers="headers" size="mini"></z-upload>
  47 + </div>
  48 + <div>
  49 + <div>图片上传:</div>
  50 + <z-upload v-model="image" type="image" action="http://47.98.245.217:7070/tms-web-api/upload/image" :limit="2" :headers="headers" size="mini"></z-upload>
  51 + </div>
  52 + <div>
  53 + <div>限制文件格式:</div>
  54 + <z-upload v-model="fileType" type="file" file-type="pdf" action="http://47.98.245.217:7070/tms-web-api/upload/image" :limit="1" :headers="headers" size="mini"></z-upload>
  55 + </div>
15 56 </div>
16 57 </template>
17 58  
... ... @@ -19,9 +60,68 @@
19 60 export default {
20 61 data() {
21 62 return {
  63 + file: '',
  64 + image: '',
  65 + fileType: '',
  66 + headers: {
  67 + 'Authorization': 'Bearer 2a6238c6-5a87-4f3f-893b-14aef14b9539'
  68 + }
  69 + }
  70 + },
  71 +}
  72 +</script>
  73 +```
  74 +
  75 +:::
  76 +
  77 +## 多选与拖拽
  78 +
  79 +可以多选上传及拖拽上传
  80 +
  81 +::: snippet `multiple`设置多选上传,`drag`设置拖拽上传
  82 +
  83 +```html
  84 +<template>
  85 + <z-upload v-model="model" action="http://47.98.245.217:7070/tms-web-api/upload/image" :headers="headers" multiple drag :limit="3"></z-upload>
  86 +</template>
  87 +
  88 +<script>
  89 +export default {
  90 + data() {
  91 + return {
22 92 model: '',
  93 + headers: {
  94 + 'Authorization': 'Bearer 2a6238c6-5a87-4f3f-893b-14aef14b9539'
  95 + },
  96 + }
  97 + },
  98 +}
  99 +</script>
  100 +```
  101 +
  102 +:::
  103 +
  104 +## 角标删除与提醒
  105 +
  106 +默认支持角标删除样式,以及配置删除前确认提示
  107 +
  108 +::: snippet `corner-close`开启角标删除,`delete-confirm`设置删除确认提示
  109 +
  110 +```html
  111 +<template>
  112 + <z-upload v-model="model" action="http://47.98.245.217:7070/tms-web-api/upload/image" :headers="headers" multiple drag corner-close delete-confirm :limit="3"></z-upload>
  113 +</template>
  114 +
  115 +<script>
  116 +export default {
  117 + data() {
  118 + return {
  119 + model: 'https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/null/3a3d0bb1-a5eb-4957-aa7a-54d004769be6.png,https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/null/a1a7e2fe-5896-44ed-9935-549050e9444c.png',
  120 + headers: {
  121 + 'Authorization': 'Bearer 2a6238c6-5a87-4f3f-893b-14aef14b9539'
  122 + },
23 123 }
24   - }
  124 + },
25 125 }
26 126 </script>
27 127 ```
... ... @@ -35,9 +135,33 @@ export default {
35 135 参数|说明|类型|可选值|默认值
36 136 -|-|-|-|-
37 137 value | 值 | String | - | -
  138 +type | 上传类型 | String | all,image,file | all
  139 +file-type | 上传文件类型限制,仅在type为file时生效 | String | - | -
  140 +disabled | 是否禁用 | Boolean | - | false
  141 +multiple | 是否支持多选文件 | Boolean | - | false
  142 +limit | 最大上传数量 | Number | - | -
  143 +drag | 是否启用拖拽上传 | Boolean | - | false
  144 +draggable | 是否启用拖拽改变顺序(需要项目安装vuedraggable并注册为draggable) | Boolean | - | false
  145 +action | 上传地址 | String | - | -
  146 +headers | 自定义请求头 | Object | - | {}
  147 +delete-confirm | 删除图片时弹出确认框 | Boolean | - | false
  148 +data | 上传时附带的额外参数 | Object | - | {}
  149 +name | 上传文件字段名 | String | - | file
  150 +response-filter | 返回值处理函数 | Function | - | -
  151 +before-upload | 上传文件之前的钩子 | Function | - | -
  152 +size | 大小 | String | mini, small, large | large
  153 +http | HTTP请求库 | Function | - | -
  154 +http-request | 自定义请求方法 | Function | - | -
  155 +corner-close | 是否开启角标删除按钮 | Boolean | - | false
38 156  
39 157 ## Events 事件
40 158  
41 159 事件名称|说明|回调参数
42 160 -|-|-
43   -change | 改变选中 | 值,选中项数据
44 161 \ No newline at end of file
  162 +upload | 单个文件上传成功后的事件 | 请求response
  163 +
  164 +## Slots 插槽
  165 +
  166 +名称|说明|方法
  167 +-|-|-
  168 +image-viewer | 自定义图片查看器 | show, index, list, close, open
... ...
packages/upload/index.vue
1 1 <template>
2   - <div class="zee-upload">
3   - <el-button type="text" @click="openViewer">查看图片</el-button>
4   - <el-image-viewer :z-index="zIndex" :initial-index="imageIndex" v-if="showViewer" :on-close="closeViewer" :url-list="previewSrcList" />
  2 + <div class="z-upload" :class="[size]">
  3 + <ul class="el-upload-list el-upload-list--picture-card">
  4 + <!-- 已上传图片列表,支持拖拽改变顺序 -->
  5 + <drag-field v-model="imageList" @change="onDragFile" :draggable="draggable">
  6 + <div v-for="(url, index) in imageList" :key="index" class="el-upload-list__item-wrapper">
  7 + <li class="el-upload-list__item">
  8 + <template v-if="type === 'all'">
  9 + <img v-if="isImage(url)" :src="url" alt class="el-upload-list__item-thumbnail" />
  10 + <div v-else alt class="el-upload-list__item-thumbnail--file" :class="url | fileTypeFilter"></div>
  11 + </template>
  12 + <template v-else>
  13 + <img v-if="type === 'image'" :src="url" alt class="el-upload-list__item-thumbnail" />
  14 + <div v-else alt class="el-upload-list__item-thumbnail--file" :class="url | fileTypeFilter"></div>
  15 + </template>
  16 + <div v-if="!cornerClose" class="el-upload-list__item-actions">
  17 + <span v-if="isImage(url)" class="el-upload-list__item-preview" @click="onPreview(url, index)">
  18 + <i class="el-icon-zoom-in"></i>
  19 + </span>
  20 + <span v-else class="el-upload-list__item-preview" @click="onDownload(url)">
  21 + <i class="el-icon-download"></i>
  22 + </span>
  23 + <span v-if="!disabled" class="el-upload-list__item-delete" @click="onRemove(index)">
  24 + <i class="el-icon-delete"></i>
  25 + </span>
  26 + </div>
  27 + <div v-else class="el-upload-list__item-actions">
  28 + <div v-if="isImage(url)" class="block-preview" @click="onPreview(url, index)">
  29 + <i class="el-icon-view"></i>
  30 + </div>
  31 + <div v-else class="block-download" @click="onDownload(url)">
  32 + <i class="el-icon-download"></i>
  33 + </div>
  34 + </div>
  35 + </li>
  36 + <div v-if="cornerClose && !disabled" class="corner-close" @click="onRemove(index)">
  37 + <i class="el-icon-close"></i>
  38 + </div>
  39 + </div>
  40 + </drag-field>
  41 + <!-- 默认上传按钮 -->
  42 + <el-upload
  43 + v-if="!limit || imageList.length < limit"
  44 + :action="action"
  45 + :data="data"
  46 + :name="name"
  47 + :headers="headers"
  48 + :file-list="fileList"
  49 + :disabled="disabled"
  50 + :multiple="multiple"
  51 + :limit="limit"
  52 + :drag="drag"
  53 + :show-file-list="false"
  54 + list-type="picture-card"
  55 + :on-exceed="onExceed"
  56 + :on-success="onSuccess"
  57 + :on-error="onError"
  58 + :before-upload="onBeforeUpload"
  59 + :http-request="isCustomRequest ? onHttpRequest : undefined"
  60 + >
  61 + <i class="el-icon-plus"></i>
  62 + </el-upload>
  63 + </ul>
  64 + <!-- 图片查看器 -->
  65 + <slot
  66 + v-if="$scopedSlots['image-viewer'] || $slots['image-viewer']"
  67 + name="image-viewer"
  68 + :show="isImageViewerShow"
  69 + :index="defaultIndex"
  70 + :list="filteredImageList"
  71 + :close="closeViewer"
  72 + :open="openViewer"
  73 + ></slot>
  74 + <template v-else>
  75 + <el-image-viewer v-if="isImageViewerShow" :initial-index="defaultIndex" :on-close="closeViewer" :url-list="filteredImageList" />
  76 + </template>
5 77 </div>
6 78 </template>
7 79  
8 80 <script>
9   -// import ElImageViewer from 'element-ui/packages/image/src/image-viewer';
10 81 import ElImageViewer from './image-viewer';
11 82  
  83 +const imgExtensions = ['.bmp', '.jpg', '.png', '.tif', '.gif', '.pcx', '.tga', '.exif', '.fpx', '.svg'];
  84 +
  85 +// 获取文件类型
  86 +const getFileType = function(url) {
  87 + return `${/\.[^.]+$/.exec(url)[0]}`.toLowerCase();
  88 +};
  89 +
12 90 export default {
13 91 name: 'Upload',
14 92 components: {
15 93 ElImageViewer,
  94 + DragField: {
  95 + props: { value: Array, draggable: Boolean },
  96 + render(h) {
  97 + // 是否开启可拖拽改变图片顺序,需要项目安装vuedraggable
  98 + if (this.draggable) {
  99 + return h(
  100 + 'draggable',
  101 + {
  102 + props: { value: this.value },
  103 + on: {
  104 + input: e => this.$emit('input', e),
  105 + change: e => this.$emit('change', e),
  106 + },
  107 + },
  108 + this.$slots.default,
  109 + );
  110 + } else {
  111 + return h('div', this.$slots.default);
  112 + }
  113 + },
  114 + },
16 115 },
17 116 props: {
18   - zIndex: {
19   - type: Number,
20   - default: 2000,
  117 + value: String,
  118 + // 是否禁用
  119 + disabled: Boolean,
  120 + // 是否支持多选文件
  121 + multiple: Boolean,
  122 + // 最大上传数量
  123 + limit: Number,
  124 + // 是否启用拖拽上传
  125 + drag: Boolean,
  126 + // 是否启用拖拽改变顺序
  127 + draggable: Boolean,
  128 + // 上传地址
  129 + action: String,
  130 + // 自定义请求头
  131 + headers: {
  132 + type: Object,
  133 + default: () => ({}),
  134 + },
  135 + // 删除图片时确认提示
  136 + deleteConfirm: Boolean,
  137 + // 上传时附带的额外参数
  138 + data: {
  139 + type: Object,
  140 + default: () => ({}),
21 141 },
  142 + // 上传文件字段名
  143 + name: {
  144 + type: String,
  145 + default: 'file',
  146 + },
  147 + // 返回值处理
  148 + responseFilter: Function,
  149 + // 上传文件之前的钩子
  150 + beforeUpload: Function,
  151 + // 上传类型
  152 + type: {
  153 + type: String,
  154 + default: 'all', // all, image, file
  155 + },
  156 + // 上传文件类型限制
  157 + fileType: String,
  158 + // 大小
  159 + size: {
  160 + type: String,
  161 + default: 'large', // mini, small, large
  162 + },
  163 + // HTTP请求库
  164 + http: Function,
  165 + // 自定义请求方法
  166 + httpRequest: Function,
  167 + // 是否开启角标删除按钮
  168 + cornerClose: Boolean,
22 169 },
23 170 data() {
24 171 return {
25   - showViewer: false,
26   - src: 'https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/vehicle/e1612ad0-3c6f-465b-ac83-cec291d3013d.jpg',
27   - previewSrcList: [
28   - 'https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/vehicle/48655e39-31cf-42ca-849d-c4a5245d005b.jpg',
29   - 'https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/vehicle/e1612ad0-3c6f-465b-ac83-cec291d3013d.jpg',
30   - 'https://zeyi-tms-test.oss-cn-hangzhou.aliyuncs.com/image/vehicle/4511c610-4f73-4f04-8e26-62e87d3cb5b1.jpg',
31   - ],
  172 + fileList: [], // ElementUI Upload 默认文件列表
  173 + imageList: [], // 图片url列表
  174 + isImageViewerShow: false, // 图片预览显示状态
  175 + currentIndex: 0, // 当前预览图片下标
32 176 };
33 177 },
34 178 computed: {
35   - imageIndex() {
36   - let previewIndex = 0;
37   - const srcIndex = this.previewSrcList.indexOf(this.src);
38   - if (srcIndex >= 0) {
39   - previewIndex = srcIndex;
  179 + // 请求自定义
  180 + isCustomRequest() {
  181 + return Boolean(this.http) || Boolean(this.httpRequest) || Boolean(this.$axios);
  182 + },
  183 + // 预览图片列表,去除文件
  184 + filteredImageList() {
  185 + if (this.type === 'all') {
  186 + return this.imageList.filter(url => imgExtensions.some(key => `${url}`.toLowerCase().includes(key)));
  187 + }
  188 + return this.imageList;
  189 + },
  190 + // 预览文件列表默认下标
  191 + defaultIndex() {
  192 + if (this.type === 'all') {
  193 + const currentUrl = this.imageList[this.currentIndex];
  194 + return this.filteredImageList.findIndex(url => url === currentUrl);
  195 + } else {
  196 + return this.currentIndex;
  197 + }
  198 + },
  199 + },
  200 + filters: {
  201 + // 处理文件拓展名对应的class
  202 + fileTypeFilter(val) {
  203 + const fileType = getFileType(val);
  204 + if (['.doc', '.docx'].includes(fileType)) {
  205 + return 'word';
  206 + }
  207 + if (['.xls', '.xlsx', '.csv'].includes(fileType)) {
  208 + return 'excel';
40 209 }
41   - return previewIndex;
  210 + if (['.ppt', '.pptx'].includes(fileType)) {
  211 + return 'ppt';
  212 + }
  213 + if (['.pdf'].includes(fileType)) {
  214 + return 'pdf';
  215 + }
  216 + if (['.zip', '.rar', '.7z'].includes(fileType)) {
  217 + return 'zip';
  218 + }
  219 + return '';
  220 + },
  221 + },
  222 + watch: {
  223 + value: {
  224 + handler(val) {
  225 + if (val) {
  226 + let imageList = [];
  227 + let fileList = [];
  228 + val.split(',').forEach(url => {
  229 + imageList.push(url);
  230 + fileList.push({ url });
  231 + });
  232 + this.imageList = imageList;
  233 + this.fileList = fileList;
  234 + } else {
  235 + this.fileList = [];
  236 + this.imageList = [];
  237 + }
  238 + },
  239 + immediate: true,
42 240 },
43 241 },
44 242 methods: {
45   - closeViewer() {
46   - this.showViewer = false;
  243 + // 判断url是否为图片
  244 + isImage(url) {
  245 + return imgExtensions.some(key => `${url}`.toLowerCase().includes(key));
  246 + },
  247 + // 删除图片
  248 + onRemove(index) {
  249 + if (this.deleteConfirm) {
  250 + this.$confirm('确定删除当前图片吗?', '提示', {
  251 + confirmButtonText: '确定',
  252 + cancelButtonText: '取消',
  253 + type: 'warning',
  254 + })
  255 + .then(() => {
  256 + this.removeImage(index);
  257 + })
  258 + .catch(() => {});
  259 + } else {
  260 + this.removeImage(index);
  261 + }
  262 + },
  263 + // 移除图片
  264 + removeImage(index) {
  265 + this.imageList.splice(index, 1);
  266 + this.fileList.splice(index, 1);
  267 + this.$emit('input', this.imageList.join(','));
  268 + },
  269 + // 预览图片
  270 + onPreview(url, index) {
  271 + this.currentIndex = index;
  272 + this.$nextTick(this.openViewer);
47 273 },
  274 + // 打开图片预览
48 275 openViewer() {
49   - this.showViewer = true;
  276 + this.isImageViewerShow = true;
  277 + },
  278 + // 关闭图片预览
  279 + closeViewer() {
  280 + this.isImageViewerShow = false;
  281 + },
  282 + // 下载文件
  283 + onDownload(url) {
  284 + window.open(url);
  285 + },
  286 + // 上传之前校验
  287 + onBeforeUpload(file) {
  288 + if (this.type === 'all') {
  289 + if (this.beforeUpload) {
  290 + return this.beforeUpload(file);
  291 + }
  292 + return true;
  293 + }
  294 + const fileType = getFileType(file.name);
  295 + if (this.type === 'image') {
  296 + if (!`${file.type}`.toLowerCase().includes('image')) {
  297 + this.$message.warning('请上传图片');
  298 + return false;
  299 + }
  300 + } else if (this.type === 'file') {
  301 + if (`${file.type}`.toLowerCase().includes('image') || (this.fileType && !fileType.includes(this.fileType))) {
  302 + this.$message.warning(`请上传${this.fileType || ''}文件`);
  303 + return false;
  304 + }
  305 + }
  306 + if (this.beforeUpload) {
  307 + return this.beforeUpload(file);
  308 + }
  309 + return true;
  310 + },
  311 + // 自定义上传
  312 + onHttpRequest(option) {
  313 + const formData = new FormData();
  314 + if (option.data) {
  315 + Object.keys(option.data).forEach(key => {
  316 + formData.append(key, option.data[key]);
  317 + });
  318 + }
  319 + formData.append(option.filename, option.file, option.file.name);
  320 + if (this.httpRequest) {
  321 + this.httpRequest({ ...option, formData });
  322 + } else {
  323 + const request = this.http || this.$axios;
  324 + if (request && request.post) {
  325 + request
  326 + .post(option.action, formData, { headers: option.headers })
  327 + .then(response => {
  328 + this.onSuccess(response.data);
  329 + })
  330 + .catch(error => {
  331 + this.onError(error);
  332 + });
  333 + }
  334 + }
  335 + },
  336 + // 上传失败
  337 + onError(err) {
  338 + this.$message.error('上传失败, 系统异常!');
  339 + },
  340 + // 上传成功
  341 + onSuccess(response) {
  342 + if (response.success) {
  343 + const { result } = response || {};
  344 + if (this.responseFilter) {
  345 + this.imageList.push(this.responseFilter(response));
  346 + } else if (result) {
  347 + this.imageList.push(result[0]);
  348 + }
  349 + this.$emit('input', this.imageList.join(','));
  350 + } else {
  351 + if (response.businessException) {
  352 + this.$message.error('上传失败!' + response.message);
  353 + } else {
  354 + this.$message.error('上传失败!');
  355 + }
  356 + }
  357 + this.$emit('upload', response);
  358 + },
  359 + // 文件超出个数限制
  360 + onExceed() {
  361 + this.$message.warning('文件个数超出限制!');
  362 + },
  363 + // 拖动图片
  364 + onDragFile() {
  365 + this.$emit('input', this.imageList.join(','));
50 366 },
51 367 },
52 368 };
53 369 </script>
54 370  
55 371 <style lang="scss">
56   -.zee-upload {
57   - display: inline-flex;
  372 +.z-upload {
  373 + &,
  374 + .el-upload-list.el-upload-list--picture-card {
  375 + display: inline-flex;
  376 + flex-wrap: wrap;
  377 + }
  378 + /* 当上传内容为文件时,默认显示对应的图标 */
  379 + .el-upload-list__item-thumbnail--file {
  380 + height: 100%;
  381 + width: 100%;
  382 + background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='60' height='60'%3E%3Cpath d='M176 160h304a472.432 472.432 0 0 1 64 64l128 208a64 64 0 0 1-64 64H176a64 64 0 0 1-64-64V224a64 64 0 0 1 64-64z' fill='%23A1CBFE'/%3E%3Cpath d='M176 288h688q64 0 64 64v432q0 64-64 64H176q-64 0-64-64V352q0-64 64-64z' fill='%234799FE'/%3E%3Cpath d='M336 688h368q32 0 32 32t-32 32H336q-32 0-32-32t32-32z' fill='%23FFF'/%3E%3Cpath d='M832 336h16q32 0 32 32v16q0 32-32 32h-16q-32 0-32-32v-16q0-32 32-32z' fill='%23A1CBFE'/%3E%3C/svg%3E");
  383 + background-repeat: no-repeat;
  384 + background-position: center;
  385 + background-size: 60%;
  386 + &.word {
  387 + background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M665.6 0l256 256v716.8a51.2 51.2 0 0 1-51.2 51.2H153.6a51.2 51.2 0 0 1-51.2-51.2V51.2A51.2 51.2 0 0 1 153.6 0zM284.16 360.96l94.72 330.24h56.32l64-248.32h2.56l64 248.32h56.32l94.72-330.24h-61.44l-61.44 250.88h-2.56l-64-250.88h-56.32L409.6 611.84h-2.56L345.6 360.96z' fill='%234E97FF'/%3E%3Cpath d='M665.6 0l256 256h-256z' fill='%23A4D2FF'/%3E%3C/svg%3E");
  388 + }
  389 + &.excel {
  390 + background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M139.456 0c-8.896 0-22.24 4.48-35.616 13.344-13.344 8.928-13.344 26.72-13.344 35.616v921.6c0 13.376 4.48 26.72 13.344 35.648 13.376 13.344 26.72 17.792 35.616 17.792h752.448c13.344 0 26.688-4.48 35.616-13.344 8.896-8.928 8.896-22.272 8.896-35.616V289.376L651.488 0h-512z' fill='%235ACC9B'/%3E%3Cpath d='M936.416 289.376h-231.52c-13.344 0-26.72-4.448-35.616-13.344-8.896-8.896-13.344-22.272-13.344-35.616V0l280.48 289.376z' fill='%23BDEBD7'/%3E%3Cpath d='M477.824 538.72L362.08 378.432h80.128l75.712 115.776 80.128-115.776h75.68L557.984 538.72l124.64 173.632H598.08L517.952 587.68l-84.608 124.672h-80.16z' fill='%23FFF'/%3E%3C/svg%3E");
  391 + }
  392 + &.ppt {
  393 + background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M880.085 1017.43h-736.17a58.539 58.539 0 0 1-58.582-58.283V58.283C85.333 26.368 111.445 0 143.915 0h513.024l281.728 288.768v670.379c0 32.298-26.112 58.282-58.582 58.282z' fill='%23FF9540'/%3E%3Cpath d='M644.437 0a15.36 15.36 0 0 0-1.152 6.059v229.888c0 32.554 27.179 59.434 60.928 59.434h234.454v-.384L645.632 0h-1.195z' fill='%23FFF' fill-opacity='.496'/%3E%3Cpath d='M511.403 573.355h-55.51v115.882h-75.178V361.045h137.898c80.086 2.219 121.6 36.608 124.63 103.894 1.152 72.149-42.667 108.373-131.84 108.373zm-6.016-154.368h-49.494v97.92h49.494c38.912-.768 58.922-17.195 60.074-48.982-1.152-31.744-21.162-47.829-60.074-48.938z' fill='%23FFF'/%3E%3C/svg%3E");
  394 + }
  395 + &.pdf {
  396 + background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M136.533 0a49.12 49.12 0 0 0-35.84 15.36C91.307 25.6 85.333 38.4 85.333 51.2v921.6a49.12 49.12 0 0 0 15.36 35.84 50.547 50.547 0 0 0 35.84 15.36h750.933a49.12 49.12 0 0 0 35.84-15.36 50.547 50.547 0 0 0 15.36-35.84V290.133L648.533 0z' fill='%23FF5562'/%3E%3Cpath d='M938.666 290.133H699.733a52.493 52.493 0 0 1-51.2-51.2V0z' fill='%23FFBBC0'/%3E%3Cpath d='M708.266 865.333c-53.76 0-101.6-92.213-127.146-152-42.667-17.92-89.6-34.133-134.827-45.226-40.106 26.56-107.52 65.76-159.626 65.76-32.427 0-55.467-16.214-64-44.374-6.827-23.04-.854-39.253 5.973-47.786q20.48-28.16 84.48-28.16c34.133 0 77.653 5.973 126.293 17.92a762.026 762.026 0 0 0 91.307-75.094c-12.8-59.733-26.453-156.16 8.533-200.533 17.067-21.333 43.52-28.16 75.094-18.773 34.986 10.24 47.786 31.573 52 47.786 14.506 58.027-52 136.534-97.334 182.667 10.24 40.107 23.04 81.92 39.254 120.32 65.066 28.96 141.813 71.627 150.4 118.56 3.413 16.213-1.707 31.573-14.507 44.373-11.094 9.333-23.04 14.507-35.84 14.507zm-79.36-129.706C661.334 801.333 692 832 708.267 832c2.56 0 5.974-.853 11.094-5.12 5.973-5.973 5.973-10.24 5.12-13.653-3.414-17.067-30.667-45.227-95.573-77.654zm-315.733-87.894c-41.813 0-53.76 10.24-57.173 14.507-.853 1.707-4.267 5.973-.853 17.92 2.56 10.24 9.333 20.48 31.573 20.48 27.307 0 66.56-15.36 112.64-42.667-33.333-6.826-62.293-10.24-86.187-10.24zm168.96-5.12a921.586 921.586 0 0 1 81.92 27.307c-9.333-24.747-17.066-50.347-23.893-75.093-18.773 16.213-38.4 32.426-58.027 47.786zM588 366.933c-9.333 0-16.213 3.414-22.187 10.24-17.92 22.187-19.626 78.507-5.973 150.187 52-55.467 80.213-106.667 73.333-133.973-.853-4.267-4.266-16.214-28.16-23.04A46.413 46.413 0 0 0 588 366.933z' fill='%23FFF'/%3E%3C/svg%3E");
  397 + }
  398 + &.zip {
  399 + background-image: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='81' height='81'%3E%3Cpath d='M61.156 685.511h910.222V921.6c0 28.444-24.178 52.622-52.622 52.622H113.778c-28.445 0-52.622-24.178-52.622-52.622V685.511z' fill='%2389D543'/%3E%3Cpath d='M61.156 352.711h910.222v332.8H61.156z' fill='%23FA6A68'/%3E%3Cpath d='M113.778 64h804.978c28.444 0 52.622 24.178 52.622 52.622v236.09H61.156v-236.09C61.156 88.178 85.333 64 113.778 64z' fill='%2360CEF8'/%3E%3Cpath d='M391.111 64H652.8v910.222H391.111z' fill='%23FDB84B'/%3E%3Cpath d='M760.889 442.311v-28.444H270.222v193.422H760.89V442.31zm-35.556 8.533v122.312H305.778V450.844h419.555z' fill='%23FFF'/%3E%3C/svg%3E");
  400 + }
  401 + }
  402 + /* 上传项外部类,用于撑开布局,显示角标按钮 */
  403 + .el-upload-list__item-wrapper {
  404 + position: relative;
  405 + display: inline-block;
  406 + margin-right: 10px;
  407 + }
  408 + /* 自定义角标删除按钮样式 */
  409 + .el-upload-list__item {
  410 + margin-right: 0 !important;
  411 + }
  412 + /* 自定义角标删除按钮样式 */
  413 + .corner-close {
  414 + position: absolute;
  415 + top: 0;
  416 + right: 0;
  417 + transform: translateX(50%) translateY(-50%);
  418 + height: 30px;
  419 + width: 30px;
  420 + min-width: 30px;
  421 + display: flex;
  422 + align-items: center;
  423 + justify-content: center;
  424 + background-color: rgba(lighten($red, 15%), 0.5);
  425 + color: #fff;
  426 + border-radius: 50%;
  427 + z-index: 20;
  428 + font-size: 16px;
  429 + cursor: pointer;
  430 + &:hover {
  431 + background-color: $red;
  432 + }
  433 + }
  434 + /* 修改卡片样式 */
  435 + .el-upload--picture-card {
  436 + line-height: 1.5;
  437 + display: flex;
  438 + align-items: center;
  439 + justify-content: center;
  440 + }
  441 + /* 修改图片按钮样式 */
  442 + .el-upload-list--picture-card .el-upload-list__item-actions {
  443 + display: flex;
  444 + align-items: center;
  445 + justify-content: space-around;
  446 + .el-upload-list__item-preview,
  447 + .el-upload-list__item-delete {
  448 + display: inline-flex;
  449 + align-items: center;
  450 + justify-content: center;
  451 + }
  452 + span + span {
  453 + margin-left: 0;
  454 + }
  455 + &::after {
  456 + display: none;
  457 + }
  458 + .block-preview,
  459 + .block-download {
  460 + height: 100%;
  461 + width: 100%;
  462 + display: flex;
  463 + align-items: center;
  464 + justify-content: center;
  465 + cursor: pointer;
  466 + }
  467 + }
  468 + /* 修改拖拽上传的默认样式 */
  469 + .el-upload-dragger {
  470 + height: 100%;
  471 + width: 100%;
  472 + display: inline-flex;
  473 + align-items: center;
  474 + justify-content: center;
  475 + border: none;
  476 + background-color: transparent;
  477 + &.is-dragover {
  478 + border-color: transparent;
  479 + }
  480 + }
  481 + /* 修改图片上传组件卡片模式默认样式 */
  482 + &.mini {
  483 + .el-upload--picture-card,
  484 + .el-upload-list--picture-card .el-upload-list__item {
  485 + height: 60px;
  486 + width: 60px;
  487 + }
  488 + .el-upload--picture-card i {
  489 + font-size: 20px;
  490 + }
  491 + .corner-close {
  492 + height: 20px;
  493 + width: 20px;
  494 + min-width: 20px;
  495 + font-size: 12px;
  496 + }
  497 + }
  498 + &.small {
  499 + .el-upload--picture-card,
  500 + .el-upload-list--picture-card .el-upload-list__item {
  501 + height: 100px;
  502 + width: 100px;
  503 + }
  504 + .corner-close {
  505 + height: 24px;
  506 + width: 24px;
  507 + min-width: 24px;
  508 + font-size: 14px;
  509 + }
  510 + }
  511 + /* 图片缩略图 */
  512 + .el-upload-list--picture-card .el-upload-list__item-thumbnail {
  513 + object-fit: cover;
  514 + }
58 515 }
59 516 </style>
... ...