Featured image of post Encapsulation of el upload - display an image after uploading

Encapsulation of el upload - display an image after uploading

Displaying an image after uploading from your computer in Vue.js

Prerequisite: You have installed Vue.js(^2.5.2) and ElementUI(^2.15.8) in your project.

Creating our own custom components

Get started with Basic HTML

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
    <el-upload 
      :action="ossUploadUrl" 
      :data="dataObj" 
      list-type="picture-card" 
      :file-list="fileList" 
      :before-upload="beforeUpload" 
      :on-remove="handleRemove" 
      :on-success="handleUploadSuccess" 
      :on-preview="handlePreview" 
      :limit="maxCount" 
      accept=".jpg, .jpeg, .png, .gif, .mp4" 
      :on-exceed="handleExceed">
        <i class="el-icon-plus"></i>
    </el-upload>
    <el-dialog :visible.sync="dialogVisible">
        <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
</div>
</template>

Defining data and props

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<script>
import { policy } from '@/api/oss'

export default {
    name: 'multiPicUpload',
    props: {
        // images array from parent template
        value: Array,
        maxCount: {
            type: Number,
            default: 5
        }
    },
    data() {
        return {
            dataObj: {
                policy: '',
                signature: '',
                key: '',
                ossaccessKeyId: '',
                dir: '',
                host: ''
            },
            dialogVisible: false,
            dialogImageUrl: null,
            ossUploadUrl: 'https://xxxxx.aliyun.com', //replace it with your back-end service
        };
    },

Compute the array of uploaded images

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
    computed: {
        fileList() {
            let fileList = [];
            if (this.value === undefined) return;
            for (let i = 0; i < this.value.length; i++) {
                fileList.push({
                    url: this.value[i]
                });
            }
            return fileList;
        }
    },

Required Methods in doc

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    methods: {
        emitInput(fileList) {
            let arr = [];
            for (let i = 0; i < fileList.length; i++) {
                arr.push(fileList[i].url);
            }
            this.$emit('input', arr)
        },
                                                
        handleRemove(file, fileList) {
            this.emitInput(fileList);
        },
                                               
        handlePreview(file) {
            this.dialogImageUrl = file.url;
            this.dialogVisible = true;
        },
                                                
        beforeUpload(file) {

            // Tell if the image is larger than 5M
            const isLt5M = file.size / 1024 / 1024 < 5;
            // const fileType = file.name.substring(file.name.lastIndexOf('.')+1)
            // Identify the type of the image
            // const isJpg = file.type ==  'image/jpeg' || file.type == 'image/jpg' || file.type == 'image/png' || file.type == 'image/gif'
            // if(!isJpg){
            //     this.$message.error('You can only upload these image file types: jpg, jpeg, png, gif!')
            //     return false
            // }

            if (!isLt5M) {
                this.$message.error('The size of the uploaded image cannot exceed 5MB!');
                return false
            }

            let _self = this;
            // 获取策略
            return new Promise((resolve, reject) => {
                // policy() is a GET request, not POST
                policy().then(response => {
                    _self.dataObj.policy = response.data.policy;
                    _self.dataObj.signature = response.data.signature;
                    _self.dataObj.ossaccessKeyId = response.data.accessKeyId;
                    _self.dataObj.key = response.data.dir + '/${filename}';
                    _self.dataObj.dir = response.data.dir;
                    _self.dataObj.host = response.data.host;
                    resolve(true)
                }).catch(err => {
                    console.log(err)
                    reject(false)
                })
            })
        },
        handleUploadSuccess(response, file, fileArr) {
            console.log('Upload successful!')
            let url = this.dataObj.host + '/' + this.dataObj.dir + '/' + fileArr.name;
            // Get the image url
            this.fileList.push({
                name: fileArr.name,
                url: url
            });
            this.emitInput(this.fileList);

        },
        handleExceed(file, fileList) {
            this.$message({
                message: 'Maximum of' + this.maxCount + 'images can be uploaded',
                type: 'warning',
                duration: 1000
            });
        },
    }
}
</script>

<style>
</style>

how to use this component

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<template>
  <div>
    <el-form-item label="device photos">
      <multipic-upload v-model="selectDevicePicFiles"></multipic-upload>
    </el-form-item>
  </div>
</template>
<script>
import MultipicUpload from "@/components/Upload/multipicUpload";
export default {
  components: { MultipicUpload },
  computed: {
    selectDevicePicFiles: {
      get: function () {
        return this.detailDevice.picUrl;
      },
      set: function (newValue) {
        console.log("get a newValue", newValue);
        if (newValue == null || newValue.length === 0) {
          this.detailDevice.picUrl = [];
        } else {
          if (newValue.length > 0) {
            this.detailDevice.picUrl = newValue;
          }
        }
      },
    },
  },
};
</script>

Finishing up

2022-08-17_17-26-54.png

Others

代码中用到的一些公共的方法–此部分可以跳过

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// some utils/methods in case you want to see it

// api/oss.js
import request from '@/utils/request'
export function policy() {
  return request({
    url:'/zm-admin/aliyun/oss/policy',
    method:'get',
  })
}

// utils/request.js
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import { getToken } from '@/utils/auth'
const service = axios.create({
  baseURL: process.env.BASE_API,
  timeout: 15000
})
service.interceptors.request.use(config => {
  if (store.getters.token) {
    config.headers['Authorization'] = getToken() // token
  }
  return config
}, error => {
  console.log(error) // for debug
  Promise.reject(error)
})
export default service

// auth.js
import Cookies from 'js-cookie'
const TokenKey = 'xxxxxToken'
export function getToken() {
  return Cookies.get(TokenKey)
}

Reference

ElementUI Docs

Built with Hugo
Theme Stack designed by Jimmy