Vue項目實現(xiàn)html5圖片上傳的示例代碼
選擇圖片 -> 預覽圖片 -> 裁剪圖片 -> 上傳圖片
我會以事例貫穿圖片接下來,就詳細的介紹每個步驟具體實現(xiàn)。
圖例

1.選擇圖片
選擇圖片有什么好講的呢?不就一個 input[type=file] ,然后點擊就可以了嗎?確實是這樣的,但是,我們想要做得更加的友好一些,比如需要過濾掉非圖片文件, 或只允許從攝像頭拍照獲取圖片等,還是需要進行一些簡單配置的。
下面就先來看看最簡單的選擇文件:
<input type="file" />
上面可以查看到非圖片類型的文件,這并不是我們想要的結(jié)果,畢竟我們只想要圖片類型??梢酝ㄟ^ accept 屬性來實現(xiàn),如下:
<input type="file" accept="image/*">
這樣就可以過濾掉非圖片類型了。但是圖片的類型可能也太多了, 有些可能服務(wù)器不支持,所以,如果想保守一些,只允許 jpg 和 png 類型,可以寫成這樣:
<input type="file" accept="image/jpg, image/jpeg, image/png">
或這樣
<input type="file" accept=".jpg, .jpeg, .jpg">
OK, 過濾非圖片的需求搞定了。但是有時候 ,產(chǎn)品還要求只能從攝像頭采集圖片,比如需要上傳證件照,防止從網(wǎng)上隨便找別人的證件上傳,那capture 屬性就可以派上用場了:
<input type="file" accept="image/*" capture>
這時候,就不能從文件系統(tǒng)中選擇照片了,只能從攝像頭采集。到了這一步,可能覺得很完美了,但是還有個問題,可能有些變態(tài)產(chǎn)品要求默認打開前置攝像頭采集圖片,比如就是想要你的自拍照片。 capture 默認調(diào)用的是后置攝像頭。默認啟用前置攝像頭可以設(shè)置 capture="user" ,如下:
<input type="file" accept="image/*" capture="user">
好啦,關(guān)于選擇圖片的就講么這么多了,有個注意的地方是,可能有些配置在兼容性上會有一些問題,所以需要在不同的機型上測試一下看看效果。
下面再來談?wù)勵A覽圖片的實現(xiàn)。
2.預覽圖片
不使用圖片預覽,點擊上傳圖片后無法查看 例如下圖:我重新?lián)Q了圖片,圖片路徑變了,但圖片沒變


2.1添加圖片預覽代碼
圖片變了可以預覽查看

源碼1: 使用 URL.createObjectURL 預覽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img {
width: 300px;
height: 200px;
}
</style>
</head>
<body>
<form action="" method="get">
<input id="inputFile" type="file" accept="image/*">
<img src="./301571.jpg" id="previewImage" alt="圖片預覽" title="活在風浪里...">
</form>
<!-- 圖片預覽 -->
<script>
const $ = document.getElementById.bind(document);
const $inputFile = $('inputFile');
const $previewImage = $('previewImage');
$inputFile.addEventListener('change', function() {
const file = this.files[0];
$previewImage.src = file ? URL.createObjectURL(file) : '';
}, this);
</script>
</body>
</html>源碼2:使用 FileReader 預覽
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
img {
width: 300px;
height: 200px;
}
</style>
</head>
<body>
<form action="" method="get">
<input id="inputFile" type="file" accept="image/*">
<img src="./301571.jpg" id="previewImage" alt="圖片預覽">
</form>
<!-- 圖片預覽 -->
<script>
const $ = document.getElementById.bind(document);
const $inputFile = $('inputFile');
const $previewImage = $('previewImage');
$inputFile.addEventListener('change', function() {
const file = this.files[0];
const reader = new FileReader();
reader.addEventListener('load', function() {
$previewImage.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}, false)
</script>
</body>
</html>預覽圖片總結(jié):
兩種方法的對比
我個人更加傾向于使用 URL.createObjectURL() 。主要原先它的 API 簡潔,同步讀取,并且他返回的是一個 URL ,比 FileReaer 返回的base64 更加精簡。兼容性上,兩者都差不多,都是在 WD 的階段。性能上的對比, 在 chrome 上, 選擇了一張 2M 的圖片, URL.createObjectURL() 用時是 0 , 而 FileReader 用時 20ms 左右。 0 感覺不太合理,雖然這個方法立刻就會返回一個 URL ,但是我猜測實際上這個 URL 指定的內(nèi)容還沒有生成好,應(yīng)該是異步生成的,然后才渲染出來的。所以并沒有很好的辦法來對比他們的性能。
3.裁剪圖片
關(guān)于圖片的裁剪,很自然的會想到使用 canvas ,確實是要通過 canvas, 但是如果全部我們自己來實現(xiàn),可能需要做比較多的工作,所以為了省力,我們可以站在巨人的肩膀上。比較優(yōu)秀的圖片裁剪庫是cropperjs , 該庫可以對圖片進行縮放、移動和旋轉(zhuǎn)。隨后會持續(xù)更新canvas,(我也在學..永遠保持謙遜,人外人天外天,拒絕凡爾賽 )
cropperjs 的詳細配置這里就不展開了 ,需要的可以自己去看文檔就好。下面我們就以這個庫為基礎(chǔ),實現(xiàn)一個裁剪人臉的例子:

源碼: 當然這個只是簡單的寫下,為了寫博客在電腦操作小伙伴要自行查看下移動端兼容
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" >
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.6/cropper.min.js"></script>
<style>
.preview-image,
.cropper-image {
max-width: 100%;
}
.cropper {
display: none;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
background: #ccc;
font-size: 0.27rem;
text-align: center;
}
.inner {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.face-container {
position: relative;
width: 320px;
height: 320px;
margin: 50px auto;
}
.cropper-modal {
background: url('https://ok.166.net/gameyw-misc/opd/squash/20191028/152551-m37snfsyu1.png') center no-repeat;
background-size: 100% 100%;
opacity: 1;
}
.cropper-bg {
background: none;
}
.cropper-view-box {
opacity: 0;
}
.tips {
font-size: 16px;
}
.toolbar {
display: flex;
justify-content: center;
margin: 50px 0;
}
.btn {
width: 150px;
line-height: 40px;
font-size: 20px;
text-align: center;
color: #fff;
background: #007fff;
}
</style>
</head>
<body>
<form name="input" action="html_form_action.php" method="get">
<input id="inputFile" type="file" accept="image/*">
<img class="preview-image" id="previewImage" src="" alt="">
<!-- cropper裁剪框 -->
<div class="cropper" id="cropper">
<div class="inner">
<div class="face-container">
<img class="cropper-image" id="cropperImage">
</div>
<div class="tips">請將面部區(qū)域置于人臉框架內(nèi)</div>
<div class="toolbar">
<div class="btn" id="confirm">確認</div>
</div>
</div>
</div>
</form>
</body>
<script>
const $ = document.getElementById.bind(document);
const $cropper = $('cropper');
const $inputFile = $('inputFile');
const $previewImage = $('previewImage');
const $cropperImage = $('cropperImage');
const $confirmBtn = $('confirm')
let cropperInstance = null;
// 選擇圖片后,顯示圖片裁剪框
$inputFile.addEventListener('change', function() {
const file = this.files[0];
if (!file) return;
$cropperImage.src = URL.createObjectURL(file);
showCropper();
}, false);
// 點擊確認按鈕,將裁剪好的圖片放到 img 標簽顯示。
$confirmBtn.addEventListener('click', function() {
const url = cropperInstance.getCroppedCanvas().toDataURL("image/jpeg", 1.0);
$cropper.style.display = 'none';
$previewImage.src = url;
}, false);
function showCropper() {
$cropper.style.display = 'block';
cropperInstance && cropperInstance.destroy();
cropperInstance = new Cropper($cropperImage, {
viewMode: 1,
aspectRatio: 1,
autoCropArea: 1,
dragMode: 'move',
guides: false,
highlight: false,
cropBoxMovable: false,
cropBoxResizable: false
});
}
</script>
</html>4.上傳
前面的操作已經(jīng)完成了圖片上傳前的準備,包括選擇圖片、預覽圖片、編輯圖片等,那接下來就可以上傳圖片了。上面的例子中,使用了 cropperInstance.getCroppedCanvas() 方法來獲取到對應(yīng)的 canvas 對象 。有了 canvas 對象就好辦了,因為 canvas.toBlob() 方法可以取得相應(yīng)的 Blob 對象,然后,我們就可以把這個 Blob 對象添加到 FromData 進行無刷新的提交了。大概的代碼如下:
change(e) {
// 1.手寫的input需要一個對象將本地圖片轉(zhuǎn)換為對應(yīng)的格式來上傳
let formData = new FormData();
//2. e.target.files就是選中的圖片的一個
formData.append("file", e.target.files[0]);
// 3. 將formData這個對象傳給修改頭像的接口
updateImg(formData).then((res) => {
//4.此時已經(jīng)傳到修改頭像接口了
//4.1 傳到修改頭像的接口后 , 在更新接口中 再次更新頭像屬性
update({ avatar: res.data.path });
//存到本地 //info是本地存儲點擊頭像獲取的個人信息,在此頁面初始調(diào)用本地存儲數(shù)據(jù),
//這里賦值info對象,因為上面渲染頭像用的是本地,所以(修改后端圖片路徑,重新調(diào)用后端更新接口后),
//還要重新賦值本地存儲,才能后端變化.本地頁面,因為是點擊頭像進入修改頁,才存儲的數(shù)據(jù),不會隨后端更新,
//所以還要重新賦值本地存儲
this.info.avatar = res.data.path;
localStorage.setItem("userInfo-Avatar", JSON.stringify(this.info));
this.show2 = false;
});
},浪哥tips: 如果在移動端,有的手機會檢測自動校正角度,導致有些角度不對可以使用 CSS 的 transfrom: rotate(-90deg) 順時針旋轉(zhuǎn) 90 度抵消掉這個角度就好。
到此這篇關(guān)于Vue項目實現(xiàn)html5圖片上傳的示例代碼的文章就介紹到這了,更多相關(guān)Vue html5圖片上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
報錯[vuex] unknown action type: userLogin問
這篇文章主要介紹了報錯[vuex] unknown action type: userLogin問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
Vue 級聯(lián)下拉框的設(shè)計與實現(xiàn)
在前端開發(fā)中,級聯(lián)選擇框是經(jīng)常用到的,這樣不僅可以增加用戶輸入的友好性,還能減少前后端交互的數(shù)據(jù)量。本文就介紹一下使用Vue實現(xiàn)級聯(lián)下拉框,感興趣的可以了解一下2021-07-07
Vue?uni-app框架實現(xiàn)上拉加載下拉刷新功能
uni-app是一個使用Vue.js(opens?new?window)開發(fā)所有前端應(yīng)用的框架,開發(fā)者編寫一套代碼,可發(fā)布到iOS、Android、Web(響應(yīng)式)、以及各種小程序(微信/支付寶/百度/頭條/飛書/QQ/快手/釘釘/淘寶)、快應(yīng)用等多個平臺2022-09-09
Vue基礎(chǔ)popover彈出框編寫及bug問題分析
這篇文章主要為大家介紹了Vue基礎(chǔ)popover彈出框編寫及bug問題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-09-09
Vue使用Echarts實現(xiàn)數(shù)據(jù)可視化的方法詳解
這篇文章主要為大家詳細介紹了Vue使用Echarts實現(xiàn)數(shù)據(jù)可視化的方法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03

