|
|
@@ -3,7 +3,6 @@
|
|
|
class="file-upload"
|
|
|
:action="uploadUrl"
|
|
|
:on-success="onSuccess"
|
|
|
- :on-remove="onRemove"
|
|
|
:headers="headers"
|
|
|
:file-list="fileList"
|
|
|
:limit="filesLimit"
|
|
|
@@ -44,171 +43,201 @@
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import resolveUrl from 'resolve-url';
|
|
|
-import axios from 'axios';
|
|
|
-export default {
|
|
|
- name: 'FileUpload',
|
|
|
- props: {
|
|
|
- single: {
|
|
|
- type: Boolean,
|
|
|
- default() {
|
|
|
- return false;
|
|
|
- }
|
|
|
- },
|
|
|
- limit: {
|
|
|
- type: Number,
|
|
|
- default() {
|
|
|
- return 10000;
|
|
|
+ import resolveUrl from 'resolve-url';
|
|
|
+ import axios from 'axios';
|
|
|
+ export default {
|
|
|
+ name: 'FileUpload',
|
|
|
+ props: {
|
|
|
+ single: {
|
|
|
+ type: Boolean,
|
|
|
+ default() {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ limit: {
|
|
|
+ type: Number,
|
|
|
+ default() {
|
|
|
+ return 10000;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ value: {},
|
|
|
+ format: {
|
|
|
+ type: String,
|
|
|
+ default: 'string'
|
|
|
}
|
|
|
},
|
|
|
- value: {}
|
|
|
- },
|
|
|
- data() {
|
|
|
- return {
|
|
|
- fileList: [],
|
|
|
- watchValue: true,
|
|
|
- uploadUrl: '',
|
|
|
- previewUrl: null
|
|
|
- };
|
|
|
- },
|
|
|
- computed: {
|
|
|
- headers() {
|
|
|
+ data() {
|
|
|
return {
|
|
|
- Authorization: 'Bearer ' + localStorage.getItem('token')
|
|
|
+ fileList: [],
|
|
|
+ emitting: false,
|
|
|
+ uploadUrl: '',
|
|
|
+ previewUrl: null
|
|
|
};
|
|
|
},
|
|
|
- filesLimit() {
|
|
|
- if (this.single) {
|
|
|
- return 1;
|
|
|
+ computed: {
|
|
|
+ headers() {
|
|
|
+ return {
|
|
|
+ Authorization: 'Bearer ' + localStorage.getItem('token')
|
|
|
+ };
|
|
|
+ },
|
|
|
+ filesLimit() {
|
|
|
+ if (this.single) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return this.limit;
|
|
|
+ },
|
|
|
+ disabled() {
|
|
|
+ return this.fileList.length >= this.limit;
|
|
|
}
|
|
|
- return this.limit;
|
|
|
- },
|
|
|
- disabled() {
|
|
|
- return this.fileList.length >= this.limit;
|
|
|
- }
|
|
|
- },
|
|
|
- created() {
|
|
|
- this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
|
|
|
- this.update(this.value);
|
|
|
- },
|
|
|
- methods: {
|
|
|
- onSuccess(res, file, fileList) {
|
|
|
- file.url = res;
|
|
|
- this.fileList = fileList;
|
|
|
},
|
|
|
- onRemove(file, fileList) {
|
|
|
- this.fileList = fileList;
|
|
|
+ created() {
|
|
|
+ this.uploadUrl = resolveUrl(this.$baseUrl, 'upload/file');
|
|
|
+ this.update(this.value);
|
|
|
},
|
|
|
- update(value) {
|
|
|
- if (this.filesLimit === 1) {
|
|
|
- this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
|
|
|
- } else {
|
|
|
- if (!value) {
|
|
|
- this.fileList = [];
|
|
|
+ methods: {
|
|
|
+ onSuccess(res, file, fileList) {
|
|
|
+ file.url = res;
|
|
|
+ this.fileList = fileList;
|
|
|
+ this.emit();
|
|
|
+ },
|
|
|
+ update(value) {
|
|
|
+ if (this.filesLimit === 1) {
|
|
|
+ if (this.format === 'json') {
|
|
|
+ this.fileList = value ? [{ name: value.name, url: value.url }] : [];
|
|
|
+ } else {
|
|
|
+ this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
|
|
|
+ }
|
|
|
} else {
|
|
|
- this.fileList = value.map(i => {
|
|
|
- return { name: i.split('/').pop(), url: i };
|
|
|
- });
|
|
|
+ if (!value) {
|
|
|
+ this.fileList = [];
|
|
|
+ } else {
|
|
|
+ this.fileList = value.map(i => {
|
|
|
+ return { name: i.name, url: i.url };
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- },
|
|
|
- onExceed(files, fileList) {
|
|
|
- console.log(files, fileList);
|
|
|
- this.$message.error(`最多上传${this.filesLimit}个文件`);
|
|
|
- },
|
|
|
- onPreview(file) {
|
|
|
- console.log(file);
|
|
|
- },
|
|
|
- removeFile(file) {
|
|
|
- if (file.status === 'uploading') {
|
|
|
- this.$refs.upload.abort(file);
|
|
|
- } else if (file.status === 'success') {
|
|
|
- let index = this.fileList.findIndex(i => i.url === file.url);
|
|
|
- if (index > -1) {
|
|
|
- this.fileList.splice(index, 1);
|
|
|
+ },
|
|
|
+ onExceed(files, fileList) {
|
|
|
+ console.log(files, fileList);
|
|
|
+ this.$message.error(`最多上传${this.filesLimit}个文件`);
|
|
|
+ },
|
|
|
+ onPreview(file) {
|
|
|
+ console.log(file);
|
|
|
+ },
|
|
|
+ removeFile(file) {
|
|
|
+ if (file.status === 'uploading') {
|
|
|
+ this.$refs.upload.abort(file);
|
|
|
+ } else if (file.status === 'success') {
|
|
|
+ let index = this.fileList.findIndex(i => i.url === file.url);
|
|
|
+ if (index > -1) {
|
|
|
+ this.fileList.splice(index, 1);
|
|
|
+ }
|
|
|
}
|
|
|
+ this.emit();
|
|
|
+ },
|
|
|
+ download(file) {
|
|
|
+ window.open(file.url, '_blank');
|
|
|
+ },
|
|
|
+ preview(file) {
|
|
|
+ this.previewUrl = file.url;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs.preview.clickHandler();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ isImage(file) {
|
|
|
+ return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.url);
|
|
|
+ },
|
|
|
+ emit() {
|
|
|
+ this.emitting = true;
|
|
|
+ if (this.filesLimit === 1) {
|
|
|
+ if (this.format === 'json') {
|
|
|
+ this.$emit(
|
|
|
+ 'input',
|
|
|
+ this.fileList[0]
|
|
|
+ ? {
|
|
|
+ name: this.fileList[0].name,
|
|
|
+ url: this.fileList[0].url
|
|
|
+ }
|
|
|
+ : null
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ this.$emit('input', this.fileList[0] ? this.fileList[0].url : null);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (this.format === 'json') {
|
|
|
+ this.$emit(
|
|
|
+ 'input',
|
|
|
+ this.fileList.map(i => {
|
|
|
+ return {
|
|
|
+ name: i.name,
|
|
|
+ url: i.url
|
|
|
+ };
|
|
|
+ })
|
|
|
+ );
|
|
|
+ } else {
|
|
|
+ this.$emit(
|
|
|
+ 'input',
|
|
|
+ this.fileList.map(i => i.url)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.emitting = false;
|
|
|
+ });
|
|
|
}
|
|
|
},
|
|
|
- download(file) {
|
|
|
- window.open(file.url, '_blank');
|
|
|
- },
|
|
|
- preview(file) {
|
|
|
- this.previewUrl = file.url;
|
|
|
- this.$nextTick(() => {
|
|
|
- this.$refs.preview.clickHandler();
|
|
|
- });
|
|
|
- },
|
|
|
- isImage(file) {
|
|
|
- return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(file.url);
|
|
|
- }
|
|
|
- },
|
|
|
- watch: {
|
|
|
- value(oldValue, value) {
|
|
|
- if (!this.watchValue) return;
|
|
|
- console.log('watch::');
|
|
|
- this.update(value);
|
|
|
- },
|
|
|
- fileList(fileList) {
|
|
|
- this.watchValue = false;
|
|
|
- if (this.filesLimit === 1) {
|
|
|
- this.$emit('input', fileList[0] ? fileList[0].url : null);
|
|
|
- } else {
|
|
|
- this.$emit(
|
|
|
- 'input',
|
|
|
- fileList.map(i => i.url)
|
|
|
- );
|
|
|
+ watch: {
|
|
|
+ value(value) {
|
|
|
+ if (this.emitting) return;
|
|
|
+ this.update(value);
|
|
|
}
|
|
|
- this.$nextTick(() => {
|
|
|
- this.watchValue = true;
|
|
|
- });
|
|
|
}
|
|
|
- }
|
|
|
-};
|
|
|
+ };
|
|
|
</script>
|
|
|
|
|
|
<style lang="less" scoped>
|
|
|
-.file-list-item {
|
|
|
- line-height: 1.8;
|
|
|
- margin-top: 5px;
|
|
|
- text-overflow: ellipsis;
|
|
|
- white-space: nowrap;
|
|
|
- overflow: hidden;
|
|
|
- cursor: pointer;
|
|
|
- .file-name {
|
|
|
- padding: 0 90px 0 20px;
|
|
|
- }
|
|
|
- .upload-progress {
|
|
|
- margin-top: 2px;
|
|
|
- position: absolute;
|
|
|
- bottom: 0;
|
|
|
- left: 20px;
|
|
|
- right: 0;
|
|
|
- width: auto;
|
|
|
- }
|
|
|
- .danger {
|
|
|
- color: #f56c6c;
|
|
|
- }
|
|
|
- .success {
|
|
|
- color: #67c23a;
|
|
|
- }
|
|
|
- .status-icon {
|
|
|
- position: absolute;
|
|
|
- left: 0;
|
|
|
- top: 0;
|
|
|
- line-height: inherit;
|
|
|
- }
|
|
|
- .opt {
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- top: 0;
|
|
|
- line-height: inherit;
|
|
|
- .opt-icon {
|
|
|
- margin-left: 15px;
|
|
|
- transition: color 0.3s;
|
|
|
- &:hover {
|
|
|
- color: #409eff;
|
|
|
+ .file-list-item {
|
|
|
+ line-height: 1.8;
|
|
|
+ margin-top: 5px;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ cursor: pointer;
|
|
|
+ .file-name {
|
|
|
+ padding: 0 90px 0 20px;
|
|
|
+ }
|
|
|
+ .upload-progress {
|
|
|
+ margin-top: 2px;
|
|
|
+ position: absolute;
|
|
|
+ bottom: 0;
|
|
|
+ left: 20px;
|
|
|
+ right: 0;
|
|
|
+ width: auto;
|
|
|
+ }
|
|
|
+ .danger {
|
|
|
+ color: #f56c6c;
|
|
|
+ }
|
|
|
+ .success {
|
|
|
+ color: #67c23a;
|
|
|
+ }
|
|
|
+ .status-icon {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ line-height: inherit;
|
|
|
+ }
|
|
|
+ .opt {
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ line-height: inherit;
|
|
|
+ .opt-icon {
|
|
|
+ margin-left: 15px;
|
|
|
+ transition: color 0.3s;
|
|
|
+ &:hover {
|
|
|
+ color: #409eff;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
</style>
|