前端选择本地文件并显示
项目中需要本地选择文件并回显,这里在Vue项目下面做了一个简单实现,记录一下
Step1:布局文件
<template>
<div class="box">
<input type="file" id="file" @change="selectFile" accept="image/png,image/jpg,image/jpeg,image/gif" multiple/>
<div class="img-grid">
<div class="img-item" v-for="item in imgList">
<img :src="item.base64">
<span>{{item.name}}</span>
</div>
</div>
</div>
</template>
html
-
input接受类型为image/png,image/jpg,image/jpeg,image/gif -
multiple设置数量不限,监听回调函数为selectFile -
回显布局为
img-grid,遍历回显数组imgList数据显示即可 -
imgList数组基本字段为base64和name,分别存放图片数据和名称
Step2:selectFile实现
- 首先获取选择的文件数据
//获取文件列表
var fileInputList = document.getElementById("file").files
js
- 初始化imgList
var that = this
//初始化数据
that.imgList = []
js
- 编写写入数据函数
采用递归形式,保证顺序处理
//递归顺序写入数据
function setImgData(input) {
var index = that.imgList.length
if (input.length > index) {
var name = fileInputList[index].name
blobToDataUrl(fileInputList[index], base64 => {
that.imgList.push({
name,
base64
})
if (input.length > index) {
//递归
setImgData(input, that.imgList)
}
})
}
}
js
其中blobToDataUrl:
//blob转为base64
function blobToDataUrl(blob, output) {
let reader = new FileReader()
reader.onload = function (evt) {
let base64 = evt.target.result
output(base64)
}
reader.readAsDataURL(blob)
}
js
- 调用写入数据函数
setImgData(fileInputList)
js
- 完整selectFile:
selectFile() {
//获取文件列表
var fileInputList = document.getElementById("file").files
var that = this
//初始化数据
that.imgList = []
setImgData(fileInputList)
//递归顺序写入数据
function setImgData(input) {
var index = that.imgList.length
if (input.length > index) {
var name = fileInputList[index].name
blobToDataUrl(fileInputList[index], base64 => {
that.imgList.push({
name,
base64
})
if (input.length > index) {
//递归
setImgData(input, that.imgList)
}
})
}
}
//blob转为base64
function blobToDataUrl(blob, output) {
let reader = new FileReader()
reader.onload = function (evt) {
let base64 = evt.target.result
output(base64)
}
reader.readAsDataURL(blob)
}
}
js
Step3:Style样式
<style scoped>
body {
margin: 0;
padding: 0;
overflow: auto !important;
}
.box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box input {
margin: 20px;
}
.box .img-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.box .img-grid .img-item {
margin: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box img {
width: 200px;
height: 120px;
}
.box span {
margin: 5px;
}
</style>
css
完整文件
<template>
<div class="box">
<input type="file" id="file" @change="selectFile" accept="image/png,image/jpg,image/jpeg,image/gif" multiple/>
<div class="img-grid">
<div class="img-item" v-for="item in imgList">
<img :src="item.base64">
<span>{{item.name}}</span>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
imgList: []
}
},
methods: {
selectFile() {
//获取文件列表
var fileInputList = document.getElementById("file").files
var that = this
//初始化数据
that.imgList = []
setImgData(fileInputList)
//递归顺序写入数据
function setImgData(input) {
var index = that.imgList.length
if (input.length > index) {
var name = fileInputList[index].name
blobToDataUrl(fileInputList[index], base64 => {
that.imgList.push({
name,
base64
})
if (input.length > index) {
//递归
setImgData(input, that.imgList)
}
})
}
}
//blob转为base64
function blobToDataUrl(blob, output) {
let reader = new FileReader()
reader.onload = function (evt) {
let base64 = evt.target.result
output(base64)
}
reader.readAsDataURL(blob)
}
}
}
}
</script>
<style scoped>
body {
margin: 0;
padding: 0;
overflow: auto !important;
}
.box {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box input {
margin: 20px;
}
.box .img-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
}
.box .img-grid .img-item {
margin: 10px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.box img {
width: 200px;
height: 120px;
}
.box span {
margin: 5px;
}
</style>
html
效果







