123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- <script>
- import UploadList from './upload-list';
- import Upload from './upload';
- import ElProgress from 'element-ui/packages/progress';
- import Migrating from 'element-ui/src/mixins/migrating';
- function noop() {}
- export default {
- name: 'ElUpload',
- mixins: [Migrating],
- components: {
- ElProgress,
- UploadList,
- Upload
- },
- provide() {
- return {
- uploader: this
- };
- },
- inject: {
- elForm: {
- default: ''
- }
- },
- props: {
- action: {
- type: String,
- required: true
- },
- headers: {
- type: Object,
- default() {
- return {};
- }
- },
- data: Object,
- multiple: Boolean,
- name: {
- type: String,
- default: 'file'
- },
- drag: Boolean,
- dragger: Boolean,
- withCredentials: Boolean,
- showFileList: {
- type: Boolean,
- default: true
- },
- accept: String,
- type: {
- type: String,
- default: 'select'
- },
- beforeUpload: Function,
- beforeRemove: Function,
- onRemove: {
- type: Function,
- default: noop
- },
- onChange: {
- type: Function,
- default: noop
- },
- onPreview: {
- type: Function
- },
- onSuccess: {
- type: Function,
- default: noop
- },
- onProgress: {
- type: Function,
- default: noop
- },
- onError: {
- type: Function,
- default: noop
- },
- fileList: {
- type: Array,
- default() {
- return [];
- }
- },
- autoUpload: {
- type: Boolean,
- default: true
- },
- listType: {
- type: String,
- default: 'text' // text,picture,picture-card
- },
- httpRequest: Function,
- disabled: Boolean,
- limit: Number,
- onExceed: {
- type: Function,
- default: noop
- }
- },
- data() {
- return {
- uploadFiles: [],
- dragOver: false,
- draging: false,
- tempIndex: 1
- };
- },
- computed: {
- uploadDisabled() {
- return this.disabled || (this.elForm || {}).disabled;
- }
- },
- watch: {
- listType(type) {
- if (type === 'picture-card' || type === 'picture') {
- this.uploadFiles = this.uploadFiles.map(file => {
- if (!file.url && file.raw) {
- try {
- file.url = URL.createObjectURL(file.raw);
- } catch (err) {
- console.error('[Element Error][Upload]', err);
- }
- }
- return file;
- });
- }
- },
- fileList: {
- immediate: true,
- handler(fileList) {
- this.uploadFiles = fileList.map(item => {
- item.uid = item.uid || (Date.now() + this.tempIndex++);
- item.status = item.status || 'success';
- return item;
- });
- }
- }
- },
- methods: {
- handleStart(rawFile) {
- rawFile.uid = Date.now() + this.tempIndex++;
- let file = {
- status: 'ready',
- name: rawFile.name,
- size: rawFile.size,
- percentage: 0,
- uid: rawFile.uid,
- raw: rawFile
- };
- if (this.listType === 'picture-card' || this.listType === 'picture') {
- try {
- file.url = URL.createObjectURL(rawFile);
- } catch (err) {
- console.error('[Element Error][Upload]', err);
- return;
- }
- }
- this.uploadFiles.push(file);
- this.onChange(file, this.uploadFiles);
- },
- handleProgress(ev, rawFile) {
- const file = this.getFile(rawFile);
- this.onProgress(ev, file, this.uploadFiles);
- file.status = 'uploading';
- file.percentage = ev.percent || 0;
- },
- handleSuccess(res, rawFile) {
- const file = this.getFile(rawFile);
- if (file) {
- file.status = 'success';
- file.response = res;
- this.onSuccess(res, file, this.uploadFiles);
- this.onChange(file, this.uploadFiles);
- }
- },
- handleError(err, rawFile) {
- const file = this.getFile(rawFile);
- const fileList = this.uploadFiles;
- file.status = 'fail';
- fileList.splice(fileList.indexOf(file), 1);
- this.onError(err, file, this.uploadFiles);
- this.onChange(file, this.uploadFiles);
- },
- handleRemove(file, raw) {
- if (raw) {
- file = this.getFile(raw);
- }
- let doRemove = () => {
- this.abort(file);
- let fileList = this.uploadFiles;
- fileList.splice(fileList.indexOf(file), 1);
- this.onRemove(file, fileList);
- };
- if (!this.beforeRemove) {
- doRemove();
- } else if (typeof this.beforeRemove === 'function') {
- const before = this.beforeRemove(file, this.uploadFiles);
- if (before && before.then) {
- before.then(() => {
- doRemove();
- }, noop);
- } else if (before !== false) {
- doRemove();
- }
- }
- },
- getFile(rawFile) {
- let fileList = this.uploadFiles;
- let target;
- fileList.every(item => {
- target = rawFile.uid === item.uid ? item : null;
- return !target;
- });
- return target;
- },
- abort(file) {
- this.$refs['upload-inner'].abort(file);
- },
- clearFiles() {
- this.uploadFiles = [];
- },
- submit() {
- this.uploadFiles
- .filter(file => file.status === 'ready')
- .forEach(file => {
- this.$refs['upload-inner'].upload(file.raw);
- });
- },
- getMigratingConfig() {
- return {
- props: {
- 'default-file-list': 'default-file-list is renamed to file-list.',
- 'show-upload-list': 'show-upload-list is renamed to show-file-list.',
- 'thumbnail-mode': 'thumbnail-mode has been deprecated, you can implement the same effect according to this case: http://element.eleme.io/#/zh-CN/component/upload#yong-hu-tou-xiang-shang-chuan'
- }
- };
- }
- },
- beforeDestroy() {
- this.uploadFiles.forEach(file => {
- if (file.url && file.url.indexOf('blob:') === 0) {
- URL.revokeObjectURL(file.url);
- }
- });
- },
- render(h) {
- let uploadList;
- if (this.showFileList) {
- uploadList = (
- <UploadList
- disabled={this.uploadDisabled}
- listType={this.listType}
- files={this.uploadFiles}
- on-remove={this.handleRemove}
- handlePreview={this.onPreview}>
- {
- (props) => {
- if (this.$scopedSlots.file) {
- return this.$scopedSlots.file({
- file: props.file
- });
- }
- }
- }
- </UploadList>
- );
- }
- const uploadData = {
- props: {
- type: this.type,
- drag: this.drag,
- action: this.action,
- multiple: this.multiple,
- 'before-upload': this.beforeUpload,
- 'with-credentials': this.withCredentials,
- headers: this.headers,
- name: this.name,
- data: this.data,
- accept: this.accept,
- fileList: this.uploadFiles,
- autoUpload: this.autoUpload,
- listType: this.listType,
- disabled: this.uploadDisabled,
- limit: this.limit,
- 'on-exceed': this.onExceed,
- 'on-start': this.handleStart,
- 'on-progress': this.handleProgress,
- 'on-success': this.handleSuccess,
- 'on-error': this.handleError,
- 'on-preview': this.onPreview,
- 'on-remove': this.handleRemove,
- 'http-request': this.httpRequest
- },
- ref: 'upload-inner'
- };
- const trigger = this.$slots.trigger || this.$slots.default;
- const uploadComponent = <upload {...uploadData}>{trigger}</upload>;
- return (
- <div>
- { this.listType === 'picture-card' ? uploadList : ''}
- {
- this.$slots.trigger
- ? [uploadComponent, this.$slots.default]
- : uploadComponent
- }
- {this.$slots.tip}
- { this.listType !== 'picture-card' ? uploadList : ''}
- </div>
- );
- }
- };
- </script>
|