前言
-
实际开发过程中,我们经常遇见需要上传文件图片功能,可以封装一个全局组件来调用
-
原理很简单,首先获取到文件或图片对象,调用自己公司文档服务器的接口,上传文件图片
-
为了方便用户体验,我们应该在上传之前开启遮罩层,上传成功之后关闭遮罩层。
-
我们还可以根据实际开发场景自定义把url和文件名称传回父组件
代码实现
1.定义api
export function uploadvideo (data) {
return request({
url: '/upload/video',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' },
data
})
}
2.在src/components/建立DocUpload文件夹/index.vue-代码如下
<template>
<el-dialog
title="上传"
:visible.sync="dialogVisible"
width="40%"
:before-close="handleClose"
>
<el-form ref="form" :model="form" size="small" label-width="80px">
<el-form-item label="文件名称:">
<el-input v-model="form.contitle" disabled></el-input>
</el-form-item>
<el-form-item label="文件上传:">
<div class="uppicture">
<input type="file" class="upinput" ref="file" @change="showimg" />
<i class="el-icon-plus" id="changes" @click="changeimg"></i>
<p>上传合同文件附件</p>
</div>
<el-button type="primary" class="uploadbutton" @click="addupload"
>上传附件</el-button
>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose" style="background: #f7f7f7" size="small"
>取 消</el-button
>
<!-- <el-button type="primary" @click="upload">确 定</el-button> -->
</span>
</el-dialog>
</template>
<script>
import { uploadvideo } from '@/api/entering'
// 遮罩层
import { Loading } from 'element-ui'
export default {
name: 'DocUpload',
data () {
return {
form: {
// 合同名称
contitle: ''
},
formdata: {}
}
},
props: {
// 显示隐藏
dialogVisible: {
type: Boolean,
// 必传
required: true
}
},
methods: {
// 关闭之前
handleClose () {
console.log('关闭之前')
// .sync语法糖,单向数据流问题,
// 父组件传递给子组件的数据,子组件直接修改会报错,需要传递给父组件修改
this.$emit('update:dialogVisible', false)
},
// 输入款获取事件
showimg () {
const that = this
console.log(that.$refs.file)
console.log(that.$refs.file.files[0])
// 文件名称复制
that.form.contitle = that.$refs.file.files[0].name
// 声明一个formdata对象
this.formdata = new FormData()
// 赋值需要传递的文件
this.formdata.append('multipartFile', that.$refs.file.files[0])
},
// 图标触发输入框事件
changeimg () {
// 点击图标时候,触发input选择文件按钮
this.$refs.file.dispatchEvent(new MouseEvent('click'))
},
// 上传附件
async addupload () {
// 上传文文件提示,未选择文件提示用户
if (!this.form.contitle) {
return this.$message.warning('请先在左侧上传文件')
}
//开启遮罩层
let loadingInstance = Loading.service({
lock: true, //lock的修改符--默认是false
text: '正在上传文件,请耐心等待', //显示在加载图标下方的加载文案
spinner: 'el-icon-loading', //自定义加载图标类名
background: 'rgba(0, 0, 0, 0.7)', //遮罩层颜色
target: document.querySelector('#futureTransferDialog') //loadin覆盖的dom元素节点
})
const res = await uploadvideo(this.formdata)
console.log('文档服务器上传文件', res)
// 传递文件存储id
this.$emit('updataurl', res.data.url)
// 回显文件名称给父组件的form表单
this.$emit('updata', this.form.contitle)
// 清空表单
this.form.contitle = ''
this.formdata = {}
// 关闭弹框
this.handleClose()
//关闭遮罩层
loadingInstance.close()
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-dialog {
border-radius: 10px;
.el-dialog__header {
border-radius: 9px 9px 0 0;
background-color: #1488c6;
padding: 8px 20px;
.el-dialog__title {
color: white;
font-size: 16px;
}
.el-dialog__headerbtn {
top: 12px;
i {
color: white;
}
}
}
.el-dialog__footer {
text-align: center;
}
.el-dialog__body {
padding: 12px;
}
.uppicture {
width: 120px;
height: 120px;
border: 1px solid #717376;
position: relative;
cursor: pointer;
input {
width: 100%;
height: 100%;
vertical-align: middle;
opacity: 0;
}
i {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 30px;
// background-color: skyblue;
}
p {
position: absolute;
bottom: -2px;
left: 50%;
word-break: keep-all;
transform: translate(-50%);
}
.uploadbutton {
position: absolute;
bottom: 0;
margin-left: 20px;
position: relative;
}
&:hover {
color: #2da9fa;
border: 1px solid #2da9fa;
p {
color: #2da9fa;
}
}
}
.uploadbutton {
position: absolute;
top: 70%;
left: 150px;
}
}
</style>
3.全局组件注册-省略
4.父组件使用
4.1组件使用
<DocUpload
:dialogVisible.sync="dialogannex"
// form是父组件表单,上传成功之后,直接通过子传父,把url和文件名称传递到父组件表单
@updata="form.name = $event"
@updataurl="form.ontractAttachment = $event"
></DocUpload>
4.2父组件data
// 上传组件开关
dialogannex: false,
// 表单
form: {},
4.3打开组件-methods
addupload () {
this.dialogannex = true
},
总结:
经过这一趟流程下来相信你也对 vue-使用input封装上传文件图片全局组件 有了初步的深刻印象,但在实际开发中我 们遇到的情况肯定是不一样的,所以我们要理解它的原理,万变不离其宗。加油,打工人!
有什么不足的地方请大家指出谢谢 -- 風过无痕