| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- <template>
- <el-upload
- class="file-upload"
- :action="uploadUrl"
- :on-success="onSuccess"
- :on-remove="onRemove"
- :headers="headers"
- :file-list="fileList"
- :limit="filesLimit"
- :on-exceed="onExceed"
- :on-preview="onPreview"
- ref="upload"
- >
- <el-button type="primary" size="mini" slot="trigger">
- 点击上传
- </el-button>
- <div class="file-list-item" slot="file" slot-scope="{ file }">
- <div class="file-name">
- <i class="status-icon el-icon-warning-outline danger" v-if="file.status === 'fail'"></i>
- <i class="status-icon el-icon-circle-check success" v-else-if="file.status === 'success'"></i>
- <i class="status-icon el-icon-loading" v-else></i>
- {{ file.name }}
- <i class="opt">
- <i class="opt-icon el-icon-search" v-if="file.status === 'success'" @click="preview(file)"></i>
- <i class="opt-icon el-icon-download" v-if="file.status === 'success'" @click="download(file)"></i>
- <i class="opt-icon el-icon-delete" @click="removeFile(file)"></i>
- </i>
- </div>
- <el-progress
- v-if="file.status === 'uploading'"
- :percentage="file.percentage"
- :show-text="false"
- :stroke-width="2"
- class="upload-progress"
- ></el-progress>
- </div>
- <el-image style="width:0;height:0;" :src="previewUrl" :preview-src-list="[previewUrl]" ref="preview">
- </el-image>
- </el-upload>
- </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;
- }
- },
- value: {}
- },
- data() {
- return {
- fileList: [],
- watchValue: true,
- uploadUrl: '',
- previewUrl: null
- };
- },
- computed: {
- headers() {
- return {
- Authorization: 'Bearer ' + localStorage.getItem('token')
- };
- },
- filesLimit() {
- if (this.single) {
- return 1;
- }
- 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;
- },
- update(value) {
- if (this.filesLimit === 1) {
- this.fileList = value ? [{ name: value.split('/').pop(), url: value }] : [];
- } else {
- if (!value) {
- this.fileList = [];
- } else {
- this.fileList = value.map(i => {
- return { name: i.split('/').pop(), url: i };
- });
- }
- }
- },
- 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);
- }
- }
- },
- 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)
- );
- }
- this.$nextTick(() => {
- this.watchValue = true;
- });
- }
- }
- };
- </script>
- <style lang="less" scoped>
- .file-list-item {
- line-height: 1.8;
- margin-top: 5px;
- 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>
|