diff --git a/components.json b/components.json index cc119630..31432118 100644 --- a/components.json +++ b/components.json @@ -46,7 +46,6 @@ "row": "./packages/row/index.js", "col": "./packages/col/index.js", "upload": "./packages/upload/index.js", - "upload-dragger": "./packages/upload/index.js", "progress": "./packages/progress/index.js", "spinner": "./packages/spinner/index.js", "message": "./packages/message/index.js", diff --git a/examples/docs/zh-CN/upload.md b/examples/docs/zh-CN/upload.md index 9940b45d..f65488ff 100644 --- a/examples/docs/zh-CN/upload.md +++ b/examples/docs/zh-CN/upload.md @@ -10,6 +10,32 @@ .upload-demo { width: 360px; } + .avatar-uploader { + .el-upload { + border: 1px dashed #d9d9d9; + border-radius: 6px; + cursor: pointer; + position: relative; + overflow: hidden; + + &:hover { + border-color: #20a0ff; + } + } + .avatar-uploader-icon { + font-size: 28px; + color: #8c939d; + width: 178px; + height: @width; + line-height: @height; + text-align: center; + } + .avatar { + width: 178px; + height: @width; + display: block; + } + } } +``` +::: + +### 照片墙 + +使用 listType 属性来设置文件列表的样式。 + +::: demo +```html + + + + +``` +::: + +### 图片列表缩略图 + +::: demo ```html + list-type="picture"> + 点击上传 +
只能上传jpg/png文件,且不超过500kb
+
+ +``` +::: + +### 拖拽上传 + +::: demo +```html + -
将文件拖到此处,或点击上传
+
将文件拖到此处,或点击上传
只能上传jpg/png文件,且不超过500kb
``` @@ -118,7 +263,7 @@ - -
将文件拖到此处,或点击上传
-
只能上传jpg/png文件,且不超过500kb
-
- -``` -::: - -### 上传单个图片 - -专门针对图片类型文件的上传,上传后在原位置显示缩略图。 - -::: demo `thumbnail-mode` 属性允许你将上传组件强制只允许图片上传,并支持展示上传文件的缩略图。 -```html - - -
将文件拖到此处,或点击上传
-
只能上传jpg/png文件,且不超过500kb
-
- -``` -::: --> - ### Attribute | 参数 | 说明 | 类型 | 可选值 | 默认值 | |---------- |-------------- |---------- |-------------------------------- |-------- | @@ -234,7 +301,7 @@ | data | 可选参数, 上传时附带的额外参数 | object | — | — | | name | 可选参数, 上传的文件字段名 | string | — | file | | with-credentials | 支持发送 cookie 凭证信息 | boolean | — | false | -| show-upload-list | 是否显示已上传文件列表 | boolean | — | true | +| show-file-list | 是否显示已上传文件列表 | boolean | — | true | | type | 上传控件类型 | string | select,drag | select | | accept | 可选参数, 接受上传的[文件类型](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#attr-accept)(thumbnail-mode 模式下此参数无效)| string | — | — | | on-preview | 可选参数, 点击已上传的文件链接时的钩子, 可以通过 file.response 拿到服务端返回数据 | function(file) | — | — | @@ -243,8 +310,9 @@ | on-error | 可选参数, 文件上传失败时的钩子 | function(err, response, file) | — | — | | on-progress | 可选参数, 文件上传时的钩子 | function(event, file, fileList) | — | — | | before-upload | 可选参数, 上传文件之前的钩子,参数为上传的文件,若返回 false 或者 Promise 则停止上传。 | function(file) | — | — | -| thumbnail-mode | 是否设置为图片模式,该模式下会显示图片缩略图 | boolean | — | false | -| fileList | 默认已上传的文件列表, 例如: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}] | array | — | [] | +| list-type | 文件列表的类型 | string | text/picture/picture-card | text | +| auto-upload | 是否在选取文件后立即进行上传 | boolean | — | true | +| fileList | 上传的文件列表, 例如: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}] | array | — | [] | ### Methods | 方法名 | 说明 | 参数 | diff --git a/packages/theme-default/src/common/transition.css b/packages/theme-default/src/common/transition.css index 042a2704..c67c6df4 100644 --- a/packages/theme-default/src/common/transition.css +++ b/packages/theme-default/src/common/transition.css @@ -57,5 +57,13 @@ } .collapse-transition { - transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out; + transition: 0.3s height ease-in-out, 0.3s padding-top ease-in-out, 0.3s padding-bottom ease-in-out; +} + +.list-enter-active, .list-leave-active { + transition: all 1s; +} +.list-enter, .list-leave-active { + opacity: 0; + transform: translateY(-30px); } diff --git a/packages/theme-default/src/upload.css b/packages/theme-default/src/upload.css index 01719e0c..4435133b 100644 --- a/packages/theme-default/src/upload.css +++ b/packages/theme-default/src/upload.css @@ -5,63 +5,110 @@ @component-namespace el { @b upload { display: inline-block; + text-align: center; @e input { display: none; } - @e inner { - display: inline-block; - position: relative; + @e tip { + font-size: 12px; + color: var(--color-base-silver); + margin-top: 7px; + } + & iframe { + position: absolute; + z-index: -1; + top: 0; + left: 0; + opacity: 0; + filter: alpha(opacity=0); + } + /* 照片墙模式 */ + @m picture-card { + background-color: #fbfdff; + border: 1px dashed #c0ccda; + border-radius: 6px; + box-sizing: border-box; + width: 148px; + height: @width; + cursor: pointer; + line-height: calc(@height - 2); - & iframe { - position: absolute; - z-index: -1; - top: 0; - left: 0; - opacity: 0; - filter: alpha(opacity=0); + i { + font-size: 28px; + color: #8c939d; + } + + &:hover { + border-color: var(--color-primary); + color: var(--color-primary); } } - @e files { - margin: 0; - padding: 0; - list-style: none; - margin-bottom: 10px; + } + @b upload-dragger { + background-color: #fff; + border: 1px dashed #d9d9d9; + border-radius: 6px; + box-sizing: border-box; + width: 360px; + height: 180px; + text-align: center; + cursor: pointer; + position: relative; + overflow: hidden; + + & .el-icon-upload { + font-size: 67px; + color: var(--color-light-silver); + margin: 40px 0 16px; + line-height: 50px; } - @e file { + + & + .el-upload__tip { + text-align: center; + } + & ~ .el-upload__files { + border-top: 1px solid rgba(var(--color-extra-light-silver), .2); + margin-top: 7px; + padding-top: 5px; + } + .el-upload__text { + color: var(--color-light-silver); + font-size: 14px; + text-align: center; + + & em { + color: var(--color-primary); + font-style: normal; + } + } + + &:hover { + border-color: var(--color-primary); + } + + @when dragOver { + background-color: rgba(32, 159, 255, .06); + border: 2px dashed var(--color-primary); + } + } + @b upload-list { + margin: 0; + padding: 0; + list-style: none; + + @e item { transition: all .5s cubic-bezier(.55,0,.1,1); font-size: 14px; color: var(--color-extra-light-black); - line-height: 32px; + line-height: 1.8; + margin-top: 5px; position: relative; box-sizing: border-box; border-radius: 4px; width: 100%; position: relative; - @e name { - color: var(--color-extra-light-black); - display: block; - margin-right: 40px; - overflow: hidden; - padding-left: 4px; - text-overflow: ellipsis; - transition: color .3s; - white-space: nowrap; - - [class^="el-icon"] { - color: var(--color-light-silver); - margin-right: 7px; - height: 100%; - line-height: inherit; - } - } - @e icon { - position: absolute; - right: 0; - top: 0; - line-height: inherit; - } & .el-progress { position: absolute; bottom: -3px; @@ -77,98 +124,206 @@ margin-right: 0; padding-right: 0; } + &:first-child { + margin-top: 10px; + } &:hover { background-color: var(--color-extra-light-gray); } @when success { - .el-upload__file__icon { - color: var(--color-success); - } - .el-upload__file__name:hover { + .el-upload-list__item-name:hover { color: var(--link-hover-color); cursor: pointer; } + .el-icon-close { + display: none; + } &:hover { - .el-upload__file__icon { + .el-icon-close { + display: inline-block; + cursor: pointer; + opacity: .75; + transform: scale(.7); + color: var(--color-extra-light-black); + &:hover { + opacity: 1; + } + } + .el-icon-circle-check, + .el-icon-check { display: none; } - .el-upload__btn-delete { - display: block; - cursor: pointer; + } + } + } + @e item-name { + color: var(--color-extra-light-black); + display: block; + margin-right: 40px; + overflow: hidden; + padding-left: 4px; + text-overflow: ellipsis; + transition: color .3s; + white-space: nowrap; + + [class^="el-icon"] { + color: var(--color-light-silver); + margin-right: 7px; + height: 100%; + line-height: inherit; + } + } + @e item-status-label { + position: absolute; + right: 10px; + top: 0; + line-height: inherit; + color: var(--color-success); + } + @e item-delete { + position: absolute; + right: 10px; + top: 0; + font-size: 12px; + color: var(--color-extra-light-black); + display: none; + + &: hover { + color: var(--color-primary); + } + } + @m picture-card { + float: left; + margin: 0; + + .el-upload-list__item { + overflow: hidden; + background-color: #fff; + border: 1px solid #c0ccda; + border-radius: 6px; + box-sizing: border-box; + width: 148px; + height: @width; + margin: 0 8px 8px 0; + display: inline-block; + + &:hover .el-upload-list__item-status-label { + display: none; + } + } + .el-upload-list__item-name { + display: none; + } + .el-upload-list__item-thumbnail { + width: 100%; + height: 100%; + } + .el-upload-list__item-status-label { + position: absolute; + right: -15px; + top: -6px; + width: 40px; + height: 24px; + background: #13ce66; + text-align: center; + transform: rotate(45deg); + box-shadow: 0 0 1pc 1px rgba(0,0,0,0.2); + + i { + font-size: 12px; + margin-top: 11px; + transform: rotate(-45deg) scale(0.8); + color: #fff; + } + } + .el-upload-list__item-actions { + position: absolute; + width: 100%; + height: 100%; + left: 0; + top: 0; + cursor: default; + text-align: center; + color: #fff; + opacity: 0; + font-size: 20px; + background-color: rgba(0, 0, 0, .5); + transition: opacity .3s; + @utils-vertical-center; + + span { + display: none; + cursor: pointer; + } + span + span { + margin-left: 15px; + } + + .el-upload-list__item-delete { + position: static; + font-size: inherit; + color: inherit; + } + + &:hover { + opacity: 1; + span { + display: inline-block; } } } - @when fail { - .el-upload__file__icon { - color: var(--color-error); + } + @m picture { + .el-upload-list__item { + overflow: hidden; + background-color: #fff; + border: 1px solid #c0ccda; + border-radius: 6px; + box-sizing: border-box; + margin-top: 10px; + + &:hover { + .el-upload-list__item-status-label { + background: transparent; + box-shadow: none; + top: -2px; + right: -12px; + + .el-icon-close { + transform: rotate(45deg) scale(.7); + } + } } } - } - @e tip { - font-size: 12px; - color: var(--color-base-silver); - margin-top: 7px; - } - @e btn-delete { - position: absolute; - right: 15px; - top: 0; - font-size: 12px; - color: var(--color-primary); - display: none; - } - /* 拖拽模式 */ - @m draggable { - background-color: var(--color-dark-white); - border: 1px solid var(--color-extra-light-silver); - box-sizing: border-box; - width: 360px; - height: 180px; - border-radius: 4px; - text-align: center; - cursor: pointer; - position: relative; - overflow: hidden; - - & .el-upload__inner { - display: block; - height: 100%; + .el-upload-list__item-thumbnail { + vertical-align: middle; + display: inline-block; + width: 70px; + height: 70px; + margin: 10px; } - & .el-icon-upload { - font-size: 67px; - color: var(--color-light-silver); - margin: 40px 0 16px; - line-height: 50px; + .el-upload-list__item-name { + display: inline-block; + vertical-align: middle; } - - & + .el-upload__tip { + .el-upload-list__item-status-label { + position: absolute; + right: -17px; + top: -7px; + width: 46px; + height: 26px; + background: #13ce66; text-align: center; - } - & ~ .el-upload__files { - margin-top: 7px; - padding-top: 5px; - border-top: 1px solid rgba(var(--color-extra-light-silver), .2); - } + transform: rotate(45deg); + box-shadow: 0 1px 1px #ccc; - @e text { - color: var(--color-light-silver); - font-size: 14px; - text-align: center; - - & em { - color: var(--color-primary); - font-style: normal; + i { + font-size: 12px; + margin-top: 12px; + transform: rotate(-45deg) scale(0.8); + color: #fff; } } - - &:not(.is-showCover):hover { - border-color: var(--color-primary); - } - - @when dragOver { - background-color: rgba(32, 159, 255, .06); - border: 2px dashed var(--color-primary); - } } } @b upload-cover { diff --git a/packages/upload-dragger/index.js b/packages/upload-dragger/index.js deleted file mode 100644 index 0774ec7d..00000000 --- a/packages/upload-dragger/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import UploadDragger from '../upload/src/upload-dragger'; - -/* istanbul ignore next */ -UploadDragger.install = function(Vue) { - Vue.component(UploadDragger.name, UploadDragger); -}; - -export default UploadDragger; diff --git a/packages/upload/_index.js b/packages/upload/_index.js deleted file mode 100644 index 45ae291f..00000000 --- a/packages/upload/_index.js +++ /dev/null @@ -1,10 +0,0 @@ -import Upload from './src'; -import UploadDragger from './src/upload-dragger'; - -/* istanbul ignore next */ -Upload.install = function(Vue) { - Vue.component(Upload.name, Upload); - Vue.component(UploadDragger.name, UploadDragger); -}; - -export default { Upload, UploadDragger }; diff --git a/packages/upload/src/cover.vue b/packages/upload/src/cover.vue deleted file mode 100644 index f607741c..00000000 --- a/packages/upload/src/cover.vue +++ /dev/null @@ -1,61 +0,0 @@ - - diff --git a/packages/upload/src/dragger.js b/packages/upload/src/dragger.js deleted file mode 100644 index 7caf7e46..00000000 --- a/packages/upload/src/dragger.js +++ /dev/null @@ -1,30 +0,0 @@ -import Cover from './cover'; - -export default { - components: { - Cover - }, - data() { - return { - dragOver: false - }; - }, - computed: { - lastestFile() { - return this.fileList[this.fileList.length - 1]; - }, - showCover() { - var file = this.lastestFile; - return this.thumbnailMode && file && file.status !== 'fail'; - }, - thumbnailMode() { - return this.$parent.thumbnailMode; - } - }, - methods: { - onDrop(e) { - this.dragOver = false; - this.uploadFiles(e.dataTransfer.files); - } - } -}; diff --git a/packages/upload/src/iframe-upload.vue b/packages/upload/src/iframe-upload.vue index f49bf364..92076bb0 100644 --- a/packages/upload/src/iframe-upload.vue +++ b/packages/upload/src/iframe-upload.vue @@ -1,9 +1,9 @@ \ No newline at end of file diff --git a/packages/upload/src/upload-list.vue b/packages/upload/src/upload-list.vue index 949e6a18..7fd786c9 100644 --- a/packages/upload/src/upload-list.vue +++ b/packages/upload/src/upload-list.vue @@ -1,20 +1,48 @@