目录

第一章 效果展示

第二章 源代码(图片上传全部详细流程)

2.1 组件封装以及el-upload使用方法

2.2 文件配置说明

2.3 axios二次封装

2.4 上传限制数量且超出不显示上传按钮

第三章 总结

第一章 效果展示

第二章 源代码(图片上传全部详细流程)

该组件是小编根据饿了么ui重新封装了一个针对图片上传的组件,可以通过子组件自定义按钮图片、图片上传数量限制、文本内容提示、是否支持拖拽、多个上传、上传文件类型等功能。小编为了针对身份证正反面上传,还加了type控制按钮背景图片展示

2.1 组件封装以及el-upload使用方法

父组件调用子组件

v-model="params.deadFront" // 双向绑定的值

:limit="1" // 限制数量

tip="请上传正面的身份证照" // tip提示

v-decorator="[ // 小编这里是个表单的添加,放了校验 -- > 可忽略

'deadFront',

{

initialValue: params.deadFront,

},

]">

main.js注册公共组件

import ImageUpload from '@/components/upload/ImageUpload' // 导入图片上传组件

Vue.component('ImageUpload', ImageUpload) // 注册图片上传组件

 子组件封装内容,包括Element组件的详细使用具体参数还是需要看官网!!!

 element官网: Element - The world's most popular Vue UI framework

// 子组件内容

2.2 文件配置说明

sortablejs说明:这是一个拖拽插件,下面是它的官官网

sortable.js中文文档 - itxst.com

 config文件配置

import fileService from '@/api/file/fileService' // api请求的文件路径

// 上传配置

export default {

apiObj: fileService, // 上传请求API对象

filename: 'file', // form请求时文件的key

successCode: 200, // 请求完成代码

maxSize: 10, // 最大文件大小 默认10MB

parseData: function (res) {

return {

src: res // 分析图片远程地址结构

}

}

}

api接口配置,注意这里怎么配置以及说明需要看我们前端axios二次封装是怎么处理的,一定要去官网看懂为什么这么配置的!!!还要跟后端商量好需要怎么发请求。

该部分:

import request from '@/utils/httpRequest' // axios的二次封装基本请求

export default {

upload: function (formData, config = {}) { // 上传函数封装并暴露

return request({

url: '/file/upload?uploadPath=userdir', // 请求路径

method: 'post', // 请求方法 post

config: config, // 请求config配置

data: formData, // 请求参数 (该参数我们前端相当于放在请求体上让后端接收的)

headers: { 'Content-Type': 'multipart/form-data' } // 请求头配置'Content-Type': 'multipart/form-data',formData的形式

})

},

// 这里看一下下载请求

downloadFile: function (params) {

return request({

url: '/file/downloadFile', // 请求路径

method: 'get', // 请求方法 get

params: params // 请求参数,该参数就放在了请求路径上

})

}

}

2.3 axios二次封装

请求方式,这个请求方式也是小编对axios的二次封装,用到的地方挺多的,不能全复制,但可以提供思路

 axios官网:axios中文文档|axios中文网 | axios

 还可以看小编的该文章,如何实现axios二次封装的:

axios二次封装-CSDN博客

import Vue from 'vue'

import axios from 'axios'

import router from '@/router'

import qs from 'qs'

import {

Message,

Loading

} from 'element-ui'

// 超时时间

axios.defaults.timeout = 100000

// 跨域请求,允许保存cookie

axios.defaults.withCredentials = true

axios.defaults.headers = {'Content-Type': 'application/json; charset=utf-8'}

// axios.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8'

// 非生产环境 && 开启代理, 接口前缀统一使用[/api]前缀做代理拦截!

const BASE_URL = process.env.NODE_ENV !== 'production' ? process.env.VUE_APP_BASE_API : process.env.VUE_APP_SERVER_URL

// 暴露的基础请求路径

axios.BASE_URL = BASE_URL

/**

* 请求拦截

*/

let loading

axios.interceptors.request.use(config => { // axios固定的方法

let showLoading = false

if (config.loading === true) {

showLoading = true

}

if (showLoading) {

loading = Loading.service({

text: config.loadingText || 'Loading...',

spinner: 'el-icon-loading',

background: 'rgba(0, 0, 0, 0.7)'

})

}

// 请求头带上token

if (Vue.cookie.get('token')) {

config.headers.token = Vue.cookie.get('token')

}

// 请求地址处理

if (!config.url.startsWith('http')) {

config.url = BASE_URL + config.url

}

const type = config.method

const arrayFormat = config.headers.arrayFormat || 'indices'

if (type === 'post' && config.headers['Content-Type'] === 'application/x-www-form-urlencoded; charset=utf-8') {

// post请求参数处理

config.data = qs.stringify(config.data, { allowDots: true, arrayFormat: arrayFormat })

} else if (type === 'get') {

// get请求参数处理

config.paramsSerializer = (params) => {

return qs.stringify(params, {

allowDots: true, arrayFormat: arrayFormat

})

}

}

return config

}, error => {

return Promise.reject(error)

})

/**

* 响应拦截

*/

axios.interceptors.response.use(response => {

if (loading) {

loading.close()

}

return response

}, error => {

if (loading) {

loading.close()

}

if (error.response.status === 408 || error.response.status === 401) { // 需要重新登录

//1、---先清空登录信息

清空了登录信息

//2、--跳转登录页

router.push({ name: 'login' })

//3、弹窗报错信息

Message({

message: error.response.data,

type: 'error',

showClose: true,

dangerouslyUseHTMLString: true,

duration: 3000

})

} else if (error.response.status === 404) { // 路径找不到

Message({

message: '404 路径找不到' + ': ' + error.response.config.url,

type: 'error',

showClose: true,

duration: 3000

})

} else if (error.response.status === 503) {

Message({

message: '503 服务不可用' + ': ' + error.response.config.url,

type: 'error',

showClose: true,

dangerouslyUseHTMLString: true,

duration: 3000

})

} else if (error.response.status === 504) {

Message({

message: '504 网络连接错误' + ': ' + error.response.data,

type: 'error',

showClose: true,

dangerouslyUseHTMLString: true,

duration: 3000

})

} else {

Message({

message: error.response.data || error.response || error,

type: 'error',

showClose: true,

dangerouslyUseHTMLString: true,

duration: 5000

})

}

return Promise.reject(error)

})

// 配置axios

export default axios

 至此所有源代码全部展示好了 

2.4 上传限制数量且超出不显示上传按钮

小编已经在前面代码中详细说明了代码中对应的功能了实现思路:通过控制台的'元素导航栏'一步一步的找到控制按钮样式的标签,通过添加类名从而控制该按钮的展示与隐藏HTML部分

CSS部分

 JS部分

 

基本需求解决 

第三章 总结

以上功能、逻辑都是小编总结出来的,实践过都没有问题的!!延伸1:功能确实实现了,瑕疵在于添加成功后按钮有一个消失的过程,这里需要我们找到对应标签的动画,应该直接隐藏掉才是。延伸2:按钮图片处理问题,小编通过require的静态路径方式得到路径的,可以试试动态展示,实现成父组件传什么图片,子组件用什么。延伸3:对model更深理解理解……最后的最后,这只是小编遇到的需求,如果大家有不同的需要也能用在该内容里,欢迎大家评论区留言,再就是有用就留下个赞吧!!!

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。