现在前端基本不是vue技术栈就是react技术栈。我们经常所用的就是vue框架了,今天我要写的是在vue中封装一个上传图片或文件的组件 支持单个或者多个 不说那么多了 上代码。
先给大家上个效果图
安装
npm install vue-upload-component --save
main.js使用
import VueUploadComponent from 'vue-upload-component'
Vue.component('file-upload', VueUploadComponent)
上组件代码
引用
import FileUpload from 'vue-upload-component';
1.html
<template>
<li class="upload">
<file-upload :postAction="url"
:data="" //传给后台的参数
:header="{}" //header请求头
:multiple="multiple" //是否支持选多个文件
accept='image/png,image/gif,image/jpeg,image/webp' //接受的文件类型
extensions='gif,jpg,jpeg,png,webp'
@input-filter="inputFilter"
@input-file="inputFile"
:input-id="refs"
:ref="refs"></file-upload>
<template v-if="isBar">
<div class="vue-progress-bar">
<div class="vue-progress-bar__inner" :style="barStyle">
</div>
</div>
</template>//这是进度条 可要可不要 最后发进度条样式 根据自己需求进行修改
</li>
</template>
2.js
export default {
components: {
FileUpload,
},
props: {
multiple: {
type: Boolean,
default: true,
},
refs: {
type: String,
default: 'upload',
},
},
data() {
return {
paths: [],
token: localStorage.getItem('token'),
url: CONF.uploadUrl,
percentage:0,//进度条百分比
isBar:false //进度条是否显示
};
},
computed:{
barStyle() {//监听进度条长度
const style = {};
style.width = this.percentage + '%';
return style;
}
},
methods: {
inputFilter(newFile, oldFile, prevent) {
if (newFile && !oldFile) {
if (/(\/|^)(Thumbs\.db|desktop\.ini|\..+)$/.test(newFile.name)) {
return prevent();
}
if (/\.(php5?|html?|jsx?)$/i.test(newFile.name)) {
return prevent();
}
}
},
inputFile(newFile) {
this.isBar = true;//上传中显示进度条
this.percentage = newFile.progress ||0
if (!newFile.active) {
newFile.active = true;
if (newFile.progress == 100 && newFile.success) {
this.isBar = false //上传成功隐藏进度条
this.paths.push(newFile.response.data.thumb_img);
this.$emit('getImgs', 获取到的文件路径); //将文件传给父组件
}
}
},
}
};
3.css样式
//上传文件
.upload-file{
position: relative;
display: inline-block;
width: 84px;
height: 22px;
text-align: center;
border-radius: 2px;
background: #ec4927;
span{
position: absolute;
left: 0;
top:0;
width: 100%;
height: 100%;
font-size: 12px;
line-height: 22px;
color: #fff;
}
input[type='file']{
display: block;
width: 100%;
height: 100%;
opacity: 0;
border: none;
}
}
//图片列表
.images-list {
font-size: 0;
line-height: 0;
margin-left: 20px;
flex: 1;
li {
width: 60px;
height: 60px;
background: #919191;
display: inline-block;
vertical-align: top;
margin-right: 5px;
margin-bottom: 10px;
position: relative;
span {
display: block;
height: 100%;
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
&.upload {
background: url("../assets/image/upload_cover.png") no-repeat center center;
background-size: auto 100%;
input[type='file'] {
background: rgba(255, 255, 255, 0);
opacity: 0;
width: 100%;
height: 100%;
position: relative;
}
}
.close {
width: 18px;
height: 18px;
display: block;
position: absolute;
background: rgba(255, 255, 255, .8) url("../assets/image/del_img.png") no-repeat center center;
background-size: auto auto;
top: 0;
right: 0;
border-bottom-left-radius: 50%;
}
}
}
//进度条展示
.vue-progress-bar{
width: 100%;
margin-top: 10px;
background: #eee;
font-size: 12px;
.vue-progress-bar__inner{
background:#ec4927;
height: 5px;
border-radius: 25px;
}
}
父组件中使用
1.引入
import uploadApp from '@/components/uploadApp.vue'
components:{
uploadApp
},
2.html
<div class="items">
<p class="name"><span>*</span>上传封面</p>
<ul class="images-list">
<li v-if="cover_img">
<i class="close" @click="cover_img=''"></i>
<img :src="uploadUrl + cover_img">
</li>
<upload-app :multiple="false" refs="cover" v-on:getImgs="getCover" v-if="cover_img == ''"></upload-app>
</ul>
</div>
<div class="items">
<p class="name"><span>*</span>上传案例</p>
<ul class="images-list">
<li v-for="(item,index) in images">
<i class="close" @click="delFile(images,index)"></i>
<img :src="uploadUrl + item">
</li>
<upload-app :multiple="true" refs="upload" v-on:getImgs="getImgs" v-if="images.length<5"></upload-app>
</ul>
</div>
3.js
export default{
components:{
uploadApp
},
data(){
return{
uploadUrl:CONF.uoloadImgUrl || '',//上传地址
cover_img:'',//单个图片地址
images:[],//多个图片列表
}
},
methods:{
//删除文件
delFile(imgs,index){
imgs.splice(index,1)
},
//获取单个图片地址
getCover(val){
this.cover_img = val
},
//获取多个图片列表
getImgs(val){
if(this.images.length<5){
this.images.push(val)
}else{
}
}
}
}
基本上就是这些 如果发现有遗漏或者问题可以留言哦