美文网首页
vue中图片、文件上传

vue中图片、文件上传

作者: 颂温暖 | 来源:发表于2020-09-17 15:00 被阅读0次

记录下项目中遇到的图片上传,亦或者文件上传的方式,总是遗忘,查资料好慢

项目采用的vue-element-admin 使用vue/vuex/vue-router/element-ui技术开发

由于request.js封装的接口类型,都是基于普通接口的请求,没有封装文件上传的接口类型
request.js代码如下

import axios from 'axios'
import { Message } from 'element-ui'
import store from '@/store'
import { getToken, removeToken, removeUserMenu, removeUserId } from '@/utils/auth'
import router from '@/router/index'

// create an axios instance
const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API + '/' + process.env.VUE_APP_API_VERSION,
    // withCredentials: true, // send cookies when cross-domain requests
    timeout: 5000 // request timeout
})

// request interceptor
service.interceptors.request.use(
    config => {
        if (store.getters.token) {
            config.headers['authorization'] = 'Bearer ' + getToken()
        }
        // console.log(config)

        const tthash = window.btoa(
            window
                .btoa(encodeURI(location.hash.replace('#/', '') ?? ''))
                .split('')
                .reverse()
                .join('')
        )
        if (config.method == 'post') {
            config.data = {
                ...config.data,
                ttname: location.pathname.replace('/', ''),
                tthash: tthash,
                tenantCode: process.env.NODE_ENV === 'development' ? process.env.VUE_APP_TENANT_CODE : '',
                productCode: process.env.NODE_ENV === 'development' ? process.env.VUE_APP_PRODUCT_CODE : ''
            }
        } else if (config.method == 'get') {
            config.params = {
                ...config.params,
                ttname: location.pathname.replace('/', ''),
                tthash: tthash
            }
        }

        return config
    },
    error => {
        return Promise.reject(error)
    }
)

// response interceptor
service.interceptors.response.use(
    response => {
        const { code, message } = response.data
        // 返回正常结果
        if (code == 10000) return response.data

        Message({
            message: message || 'Error',
            type: 'warning',
            duration: 1.5 * 1000
        })

        return Promise.reject(response.data)
    },
    error => {
        if (error.response && error.response.status == 401) {
            removeToken()
            removeUserMenu()
            removeUserId()
            // store.dispatch('user/logout', store.getters.userId)
            Message({
                message: error.message,
                type: 'error',
                duration: 1.5 * 1000
            })
            router.push({ path: '/login' })
        } else if (error.response && error.response.status == 403) {
            Message({
                message: error.message,
                type: 'error',
                duration: 1.5 * 1000
            })
            router.push({ path: '/403' })
        }
        return Promise.reject(error.data || {})
    }
)

export default service

以上代码可以看出,文件上传接口不在此列,所以文件上传接口需要单独编写

编写的时候需要注意,请求的一些参数,请求头,都需要另外拿出来放到文件上传接口中

下面来主要说一下,文件上传写法,采用了,element-ui中的el-upload组件,代码如下

<el-form-item label="LOGO" prop="logo">
    <el-upload
      class="avatar-uploader"
      action="#"
      :show-file-list="false"
      accept="image/*"
      :http-request="upload"
    >
    <img :src="from.logo" class="avatar" />
   </el-upload>
</el-form-item>

*action --上传的地址,必选
*show-file-list --是否显示已上传文件列表
*accept --接受上传的文件类型,这里image/*是指图片格式的
*:http-request --覆盖默认的上传行为,可以自定义上传的实现,这里使用这个,上面action可以忽略

然后我们这里使用了:http-request="upload"自定义的方式,那么下面就来看看这种方式实现,
代码如下:

import axios from 'axios'
import { getToken } from '@/utils/auth'

// 上传图片
        upload(e) {
          //这是参数配置,可以忽略
            const tthash = window.btoa(
                window
                    .btoa(encodeURI(location.hash.replace('#/', '') ?? ''))
                    .split('')
                    .reverse()
                    .join('')
            )
            //使用FormData 的最大优点就是可以异步上传二进制文件。
            //而图片,文件之类的文件是二进制,接口接收参数也是接收的二进制
            //可以先通过new关键字创建一个空的 FormData 对象,然后使用 append() 方法向该对象里添加字段
            //(字段的值可以是一个 Blob 对象,File对象或者字符串,剩下其他类型的值都会被自动转换成字符串)。

            //也可以用一个已有的form元素来初始化FormData对象
            const formData = new FormData()

            //这里是把上传接口所有的参数都append到formData中
            formData.append('img', e.file)
            formData.append('type', 'market')
            formData.append('ttname', location.pathname.replace('/', ''))
            formData.append('tthash', tthash)
            formData.append('tenantCode', process.env.NODE_ENV === 'development' ? process.env.VUE_APP_TENANT_CODE : '')
            formData.append('productCode', process.env.NODE_ENV === 'development' ? process.env.VUE_APP_PRODUCT_CODE : '')
            const config = {
                headers: {
                    'Content-Type': 'multipart/form-data',
                    'authorization': 'Bearer ' + getToken()
                }
            }
            //接口调用
            axios.post('/api/tenant/assist/upload_image', formData, config).then((res) => {
                this.from.logo = res.data.data.filename
            })
        },
//使用方法

upload(e) {
    this.getBase64(e.file).then((res) => {
        console.log(res)
    })
}

//图片文件转base64方法
getBase64(file) {
            return new Promise(function(resolve, reject) {
                const reader = new FileReader()
                let imgResult = ''
                reader.readAsDataURL(file)
                reader.onload = function() {
                    imgResult = reader.result
                }
                reader.onerror = function(error) {
                    reject(error)
                }
                reader.onloadend = function() {
                    resolve(imgResult)
                }
            })
        },

方法注释,都写到了代码注释中,细看就能看明白

后续会持续更新

相关文章

网友评论

      本文标题:vue中图片、文件上传

      本文链接:https://www.haomeiwen.com/subject/qgrhyktx.html