在過去,瀏覽器是不允許我們讀取本地的文件,包括圖片。因此,當(dāng)我們需要預(yù)覽一個圖片的時候,往往先將它傳送到服務(wù)端,然后服務(wù)端返回一個訪問 url 地址,達(dá)到預(yù)覽圖片的功能。如今,隨著標(biāo)準(zhǔn)不斷的改善,JavaScript 里的 API 越來越多,我們可以通過直接讀取本地文件的方式來加載我們想要看到的文本或者圖片,一定程度上減少了服務(wù)端的壓力。
Upload 組件參考文檔:https://www.iviewui.com/components/upload
文檔提供的參考代碼:
<template>
<div class="demo-upload-list" v-for="item in uploadList">
<template v-if="item.status === 'finished'">

<div class="demo-upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(item.name)"></Icon>
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
</div>
</template>
<template v-else>
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
</template>
</div>
<Upload
ref="upload"
:show-upload-list="false"
:default-file-list="defaultList"
:on-success="handleSuccess"
:format="['jpg','jpeg','png']"
:max-size="2048"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
multiple
type="drag"
action="http://jsonplaceholder.typicode.com/posts/"
style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="camera" size="20"></Icon>
</div>
</Upload>
<Modal title="查看圖片" v-model="visible">

</Modal>
</template>
<script>
export default {
data () {
return {
defaultList: [
{
'name': 'a42bdcc1178e62b4694c830f028db5c0',
'url': 'https://o5wwk8baw.qnssl.com/a42bdcc1178e62b4694c830f028db5c0/avatar'
},
{
'name': 'bc7521e033abdd1e92222d733590f104',
'url': 'https://o5wwk8baw.qnssl.com/bc7521e033abdd1e92222d733590f104/avatar'
}
],
imgName: '',
visible: false,
uploadList: []
}
},
methods: {
handleView (name) {
this.imgName = name;
this.visible = true;
},
handleRemove (file) {
// 從 upload 實例刪除數(shù)據(jù)
const fileList = this.$refs.upload.fileList;
this.$refs.upload.fileList.splice(fileList.indexOf(file), 1);
},
handleSuccess (res, file) {
// 因為上傳過程為實例,這里模擬添加 url
file.url = 'https://o5wwk8baw.qnssl.com/7eb99afb9d5f317c912f08b5212fd69a/avatar';
file.name = '7eb99afb9d5f317c912f08b5212fd69a';
},
handleFormatError (file) {
this.$Notice.warning({
title: '文件格式不正確',
desc: '文件 ' + file.name + ' 格式不正確,請上傳 jpg 或 png 格式的圖片。'
});
},
handleMaxSize (file) {
this.$Notice.warning({
title: '超出文件大小限制',
desc: '文件 ' + file.name + ' 太大,不能超過 2M。'
});
},
handleBeforeUpload () {
const check = this.uploadList.length < 5;
if (!check) {
this.$Notice.warning({
title: '最多只能上傳 5 張圖片。'
});
}
return check;
}
},
mounted () {
this.uploadList = this.$refs.upload.fileList;
}
}
</script>
<style>
.demo-upload-list{
display: inline-block;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0,0,0,.2);
margin-right: 4px;
}
.demo-upload-list img{
width: 100%;
height: 100%;
}
.demo-upload-list-cover{
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,.6);
}
.demo-upload-list:hover .demo-upload-list-cover{
display: block;
}
.demo-upload-list-cover i{
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
</style>
自己實現(xiàn)手動上傳:
<template>
<div>
<div class="demo-upload-list" v-for="item in uploadList">

<div class="demo-upload-list-cover">
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
</div>
</div>
<Upload ref="upload" :show-upload-list="false" :format="['jpg','jpeg','png']" :max-size="2048" :before-upload="handleBeforeUpload" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" type="drag" action="http://jsonplaceholder.typicode.com/posts/" style="display: inline-block;width:58px;">
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="camera" size="20"></Icon>
</div>
</Upload>
</div>
</template>
<script>
export default {
methods: {
data(){
return {
uploadList: []
}
},
handleBeforeUpload(file) {
// 創(chuàng)建一個 FileReader 對象
let reader = new FileReader()
// readAsDataURL 方法用于讀取指定 Blob 或 File 的內(nèi)容
// 當(dāng)讀操作完成,readyState 變?yōu)?DONE,loadend 被觸發(fā),此時 result 屬性包含數(shù)據(jù):URL(以 base64 編碼的字符串表示文件的數(shù)據(jù))
// 讀取文件作為 URL 可訪問地址
reader.readAsDataURL(file)
const _this = this
reader.onloadend = function (e) {
file.url = reader.result
_this.uploadList.push(file)
}
},
handleRemove(file) {
this.uploadList.splice(this.uploadList.indexOf(file), 1)
},
handleFormatError(file) {
this.$Notice.warning({
title: '文件格式不正確',
desc: '文件 ' + file.name + ' 格式不正確,請上傳 jpg 或 png 格式的圖片。'
})
},
handleMaxSize(file) {
this.$Notice.warning({
title: '超出文件大小限制',
desc: '文件 ' + file.name + ' 太大,不能超過 2M。'
})
}
}
}
</script>
<style scoped>
.demo-upload-list {
display: inline-block;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0, 0, 0, .2);
margin-right: 4px;
}
.demo-upload-list img {
width: 100%;
height: 100%;
}
.demo-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, .6);
}
.demo-upload-list:hover .demo-upload-list-cover {
display: block;
}
.demo-upload-list-cover i {
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
.ivu-icon {
line-height: 58px;
}
</style>