Vue上传图片预览组件
父组件:
<template>
<div>
<h4>基于Vue.2X的html5上传图片组件</h4>
<div style="width: 502px;">
<uploader :src="'/api/imgsupload'"></uploader>
</div>
</div>
</template>
<script>
import uploader from './uploader.vue'
export default {
data() {
return {}
},
components: {
uploader
}
}
</script>
子组件:
<template>
<div class="vue-uploader">
<div class="file-list">
<section v-for="(file, index) of files" class="file-item draggable-item">
<img :src="file.src" alt="" ondragstart="return false;">
<p class="file-name">{{file.name}}</p>
<span class="file-remove" @click="remove(index)">+</span>
</section>
<section v-if="status == 'ready'" class="file-item">
<div @click="add" class="add">
<span>+</span>
</div>
</section>
</div> <section v-if="files.length != 0" class="upload-func">
<div class="progress-bar">
<section v-if="uploading" :width="(percent * 100) + '%'">{{(percent * ) + '%'}}</section>
</div>
<div class="operation-box">
<button v-if="status == 'ready'" @click="submit">上传</button>
<button v-if="status == 'finished'" @click="finished">完成</button>
</div>
</section>
<input type="file" accept="image/*" @change="fileChanged" ref="file" multiple="multiple">
</div>
</template>
<script>
export default {
props: {
src: {
type: String,
required: true
}
},
data() {
return {
status: 'ready',
files: [],
uploading: false,
percent:
}
},
methods: {
add() {
this.$refs.file.click()//调用file的click事件
},
submit() {
if (this.files.length === ) {
console.warn('no file!');
return
}
//当点击上传按钮时,将会遍历所有选中的文件,并添加到自定义的FormData中
const formData = new FormData()
this.files.forEach((item) => {
formData.append(item.name, item.file)
})
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', this.uploadProgress, false)
xhr.open('POST', this.src, true)
this.uploading = true
xhr.send(formData)
xhr.onload = () => {
this.uploading = false
if (xhr.status === || xhr.status === ) {
this.status = 'finished'
console.log('upload success!')
} else {
console.log(`error:error code ${xhr.status}`)
}
}
},
finished() {
this.files = []
this.status = 'ready'
},
remove(index) {
this.files.splice(index, )
},
fileChanged() {
const list = this.$refs.file.files
for (let i = ; i < list.length; i++) {
if (!this.isContain(list[i])) {
const item = {
name: list[i].name,
size: list[i].size,
file: list[i]
}
this.html5Reader(list[i], item)
this.files.push(item)
}
}
this.$refs.file.value = ''
},
// 将图片文件转成BASE64格式
html5Reader(file, item){
const reader = new FileReader()
reader.onload = (e) => {
this.$set(item, 'src', e.target.result)
}
reader.readAsDataURL(file)
},
isContain(file) {
return this.files.find((item) => item.name === file.name && item.size === file.size)
},
uploadProgress(evt) {
const component = this
if (evt.lengthComputable) {
const percentComplete = Math.round((evt.loaded * ) / evt.total)
component.percent = percentComplete /
} else {
console.warn('upload progress unable to compute')
}
}
}
}
</script>
<style>
.vue-uploader {
border: 1px solid #e5e5e5;
}
.vue-uploader .file-list {
padding: 10px 0px;
}
.vue-uploader .file-list:after {
content: '';
display: block;
clear: both;
visibility: hidden;
line-height: ;
height: ;
font-size: ;
}
.vue-uploader .file-list .file-item {
float: left;
position: relative;
width: 100px;
text-align: center;
}
.vue-uploader .file-list .file-item img{
width: 80px;
height: 80px;
border: 1px solid #ececec;
}
.vue-uploader .file-list .file-item .file-remove {
position: absolute;
right: 12px;
display: none;
top: 4px;
width: 14px;
height: 14px;
color: white;
cursor: pointer;
line-height: 12px;
border-radius: %;
transform: rotate(45deg);
background: rgba(, , , 0.5);
}
.vue-uploader .file-list .file-item:hover .file-remove {
display: inline;
}
.vue-uploader .file-list .file-item .file-name {
margin: ;
height: 40px;
word-break: break-all;
font-size: 14px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: ;
-webkit-box-orient: vertical;
}
.vue-uploader .add {
width: 80px;
height: 80px;
margin-left: 10px;
float: left;
text-align: center;
line-height: 80px;
border: 1px dashed #ececec;
font-size: 30px;
cursor: pointer;
}
.vue-uploader .upload-func {
display: flex;
padding: 10px;
margin: 0px;
background: #f8f8f8;
border-top: 1px solid #ececec;
}
.vue-uploader .upload-func .progress-bar {
flex-grow: ;
}
.vue-uploader .upload-func .progress-bar section {
margin-top: 5px;
background: #00b4aa;
border-radius: 3px;
text-align: center;
color: #fff;
font-size: 12px;
transition: all .5s ease;
}
.vue-uploader .upload-func .operation-box {
flex-grow: ;
padding-left: 10px;
}
.vue-uploader .upload-func .operation-box button {
padding: 4px 12px;
color: #fff;
background: #007ACC;
border: none;
border-radius: 2px;
cursor: pointer;
}
.vue-uploader > input[type="file"] {
display: none;
}
</style>
效果:


Vue上传图片预览组件的更多相关文章
- [js开源组件开发]-手机端照片预览组件
手机端照片预览组件 可怜的我用着华为3C手机,用别人现成的组件都好卡,为了适应我这种屌丝,于是自己简化写了一版的照片预览效果,暂时无缩放功能,以后可能有空再加吧,你也可以自己加下,这是个github上 ...
- HTML5上传图片预览
<!DOCTYPE html> <html> <head> <title>HTML5上传图片预览</title> <meta http ...
- jquery实现上传图片预览(需要浏览器支持html5)
jquery实现上传图片预览(需要浏览器支持html5) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN&q ...
- HTML5上传图片预览功能
HTML5上传图片预览功能 HTML代码如下: <!-- date: 2018-04-27 14:41:35 author: 王召波 descride: HTML5上传图片预览功能 --> ...
- 图片预览组件PhotoView
图片预览组件PhotoView PhotoView是一款图片预览组件,广泛应用于大图的查看.该组件支持图片手势缩放.旋转等功能.它可以很好的和ViewPager.Picasso等组件结合,实现各种复杂 ...
- JS 上传图片 + 预览功能(一)
JS 上传图片 + 预览功能 <body> <input type="file" id="fileimg1" style="disp ...
- js兼容火狐显示上传图片预览效果
js兼容火狐显示上传图片预览效果[谷歌也适用] <!doctype html> <html> <head> <meta content="text/ ...
- 通过HTML5 FileReader实现上传图片预览功能
原文:http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201706224590.html 在上传图片到服务器之前,我们希望可以预览一下要上传的图片. ...
- 去除ckeditor上传图片预览中的英文字母
去除ckeditor上传图片预览中的英文字母 CKEDITOR.replace('text', { filebrowserImageUploadUrl : 'upload_img.do', langu ...
随机推荐
- Cmd2001的毒瘤水题题解
怕不是我再不写题解这题就该成没人做也没人会的千古谜题了...... T1: 仔细分析题面,发现相同就是广义SAM上节点相同,相似就是广义SAM上为从根到某个点路径的前缀..直接SAM上跑从根开始,每个 ...
- [USACO3.2]Sweet Butter
题目大意: 给定一张$k$个结点,$m$条边的无向图,其中有$n$个点被标记,在这$k$个点中找出一个点使得这个点到那$n$个点的最短距离之和最小,求出这个距离和. 思路: 对于每个标记结点跑最短路, ...
- zoj 3460 二分+二分图匹配
不错的思想 /* 大致题意: 用n个导弹发射塔攻击m个目标.每个发射架在某个时刻只能为 一颗导弹服务,发射一颗导弹需要准备t1的时间,一颗导弹从发 射到击中目标的时间与目标到发射架的距离有关.每颗导弹 ...
- 关于dubbo服务的xml配置文件报错的问题
在配置dubbo服务的过程中,经常会遇到虽然程序能够跑起来,但是配置文件一堆红叉,虽然不影响功能,但是确实很让人恶心. 报错信息如下: Multiple annotations found at th ...
- c# -- 解决vs使用本地iis运行项目支持局域网访问的问题(附防火墙端口开放步骤)
用vs运行项目时,有时候需要局域网内不同设备进行访问调试~ 以前解决过这个问题,这次用了部新电脑,问题又出现了,改了配置还是不行,原来还差了一步防火墙端口开放访问. 于是写了这篇分享,备忘~ 操作步骤 ...
- Extended APDU support
http://pcsclite.alioth.debian.org/ccid_extended_apdu.html To be able to use an extended APDU you nee ...
- SQLSERVER误删Windows登录用户验证方式使用Windows身份验证的解决方法
今天看到这篇文章:没有了SA密码,无法Windows集成身份登录,DBA怎么办? 想起来之前着急哥问我的一个问题,一个DBA删除了Windows登录用户,而且SQLSERVER服务器的验证方式是Win ...
- 使用Gitblit 搭建Windows Git服务器
使用Gitblit 搭建Windows Git服务器 整理使用Gitblit搭建Git服务器的步骤. 目录 使用Gitblit 搭建Windows Git服务器 目录 下载安装 配置 运行 客户端运行 ...
- 【Go入门教程2】基本构成元素:标识符(identifier)、关键字(keyword 25个)、字面量(literal)、分隔符(delimiter)、和 操作符(operator)
基本构成要素 Go 的语言符号 又称 词法元素,共包括 5 类内容——标识符(identifier).关键字(keyword).字面量(literal).分隔符(delimiter) 和 操作符(op ...
- BootstrapClassloader ExtClassloader AppClassloader
http://www.importnew.com/26269.html import java.net.URL; class test9 { public static void main(Str ...