vue3?頭像上傳?組件功能實(shí)現(xiàn)
vue3 頭像上傳 組件功能

- 用到了
自定義組件v-model的雙向綁定 - 使用
input的type=file這個(gè)原生html元素,通過(guò)監(jiān)聽change事件,獲取到選擇的文件(注意,選擇完文件值后,要把這個(gè)隱藏的input的type=file元素的value置為空,否則,下次選擇同樣的圖片,將不會(huì)觸發(fā)change事件) - 使用
axios + formData 上傳文件 - 后臺(tái)做保存文件,以及
靜態(tài)資源目錄映射即可
前端
AvatarUpload.vue
<template>
<div class="avatar-upload-wrapper">
<!-- {{ modelValue }} -->
<div :class="['avatar-box',{'avatar-box-border':imgUrl?false:true}]" @click="clickAvatarBox" :style="{width: size + 'px',height: size + 'px'}">
<!-- 隱藏的input的type=file -->
<input type="file" hidden ref="fileInputRef" accept="image/x-png,image/gif,image/jpeg,image/bmp" @change="changeFile">
<img v-if="imgUrl" :src="imgUrl" alt="">
<div v-else class="avatar-marker">
<i class="iconfont icon-jiahao"></i>
</div>
</div>
</div>
</template>
<script setup>
import Messager from '@/utils/messager'
import axiosInstance from '@/utils/request'
import { ref,reactive,watch } from 'vue'
const emits = defineEmits(['update:modelValue'])
const props = defineProps({
size: {
type: Number,
default: 64
},
modelValue: {
type: String,
default: '' // 默認(rèn)頭像鏈接地址
},
maxSize: {
type:Number,
default: 5 // 默認(rèn)最大不超過(guò)5M
},
serverUrl: {
type:String,
default: 'http://localhost:9091/static/img'
}
})
const fileInputRef =ref(null)
// const imgUrl = ref('http://localhost:9091/static/img/avatar/3026520210706112210298.png')
const imgUrl = ref(props.modelValue)
// console.log(imgUrl.value);
// 監(jiān)聽頭像url改變(打開彈框時(shí), 傳入的圖片地址變化時(shí), 同步修改imgUrl)
watch(()=>props.modelValue,(newVal,oldVal)=>{
imgUrl.value = newVal
})
function clickAvatarBox() {
fileInputRef.value.click()
}
function changeFile() {
console.log(123,fileInputRef.value.files[0].size);
// 獲取更改后的文件
let file = fileInputRef.value.files[0]
// 校驗(yàn)文件大小
if(file.size / 1024 / 1024 > props.maxsize) {
Messager.error('文件超過(guò)指定大小')
}
// 執(zhí)行文件上傳
let formData = new FormData()
formData.append("mfile", file)
formData.append("type", "avatar")
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'a':'b' // 隨便自己帶個(gè)什么請(qǐng)求頭
}
} // 這個(gè)config可以不必?cái)y帶, 當(dāng)使用FormData傳參時(shí),
// axios會(huì)自己帶上'Content-Type': 'multipart/form-data',請(qǐng)求頭
axiosInstance.post('/file/uploadFile',formData,config ).then(res=>{
console.log(res,'上傳成功');
imgUrl.value = props.serverUrl + res
let img = new Image()
img.src = imgUrl.value
img.onload = ()=>{
emits('update:modelValue', imgUrl.value)
}
})
}
</script>
<style lang="scss" scoped>
.avatar-box-border {
border: 1px dashed #409eff !important;
}
.avatar-box {
border-radius: 50%;
margin-left: 20px;
cursor: pointer;
position: relative;
border: 2px solid #eee;
overflow: hidden;
&:hover::before {
content:'';
display: block;
position: absolute;
width: 100%;
height: 100%;
background: rgba(0,0,0,.03);
}
img {
width: 100%;
height: 100%;
object-fit: cover;
}
.avatar-marker {
position: absolute;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #409eff;
i.iconfont {
font-size: 24px;
}
}
}
</style>使用AvatarUpload.vue
<el-dialog v-model="userDialogVisible" width="450">
<el-form :model="userForm" :rules="userFormRules" label-width="80">
<el-form-item label="昵稱" prop="nickname">
<el-input v-model="userForm.nickname" style="width: 300px;"></el-input>
</el-form-item>
<!-- 使用頭像上傳組件 -->
<el-form-item label="頭像" prop="avatar">
<avatar-upload v-model="userForm.avatar" />
</el-form-item>
<el-form-item label="個(gè)性簽名" prop="bio">
<el-scrollbar>
<el-input type="textarea" :rows="3" v-model="userForm.bio" style="width: 300px;"></el-input>
</el-scrollbar>
</el-form-item>
<el-form-item label="網(wǎng)站鏈接" prop="website">
<el-input v-model="userForm.website" style="width: 300px;"></el-input>
</el-form-item>
<el-form-item label="是否可用" prop="disabled">
<el-switch v-model="userForm.disabled" :active-value="0" :inactive-value="1" active-color="#13ce66"
inactive-color="#eaecf0">
</el-switch>
</el-form-item>
<el-form-item>
<div style="margin-left: auto;">
<el-button @click="userDialogVisible = false">取消</el-button>
<el-button type="primary" @click="handleSave">確定</el-button>
</div>
</el-form-item>
</el-form>
</el-dialog>后端
上傳接口
@PostMapping("uploadFile")
public Result<String> uploadFile(@RequestParam("mfile") MultipartFile mfile, String type) {
return Result.ok(fileService.saveFile(mfile,type));
}
@Override
public String saveFile(MultipartFile mfile, String type) {
String filePath = FilePathEnum.type(type).getPathPrefix() + SnowflakeIdWorker.generateId().substring(0, 8) + mfile.getOriginalFilename();
String targetFilePath = fileSavePath + filePath;
try {
mfile.transferTo(new File(targetFilePath));
} catch (IOException e) {
throw BizException.SAVE_FILE_ERR;
}
return filePath;
}配置mvc
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**")
.addResourceLocations("file:D:\\Projects\\boot-blog\\src\\main\\resources\\static\\");
}
}到此這篇關(guān)于vue3 頭像上傳 組件的文章就介紹到這了,更多相關(guān)vue3 頭像上傳 組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- springboot+vue實(shí)現(xiàn)七牛云頭像的上傳
- vue實(shí)現(xiàn)頭像上傳功能
- Vue?vant-ui使用van-uploader實(shí)現(xiàn)頭像上傳功能
- 利用nodeJS+vue圖片上傳實(shí)現(xiàn)更新頭像的過(guò)程
- Springboot+Vue-Cropper實(shí)現(xiàn)頭像剪切上傳效果
- vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁(yè)面的方法
- 詳解Vue+axios+Node+express實(shí)現(xiàn)文件上傳(用戶頭像上傳)
- node+vue實(shí)現(xiàn)用戶注冊(cè)和頭像上傳的實(shí)例代碼
- vue+golang實(shí)現(xiàn)上傳微信頭像功能
相關(guān)文章
Vue中JS動(dòng)畫與Velocity.js的結(jié)合使用
這篇文章主要介紹了Vue中JS動(dòng)畫與Velocity.js的結(jié)合使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02
Vue.js 通過(guò)jQuery ajax獲取數(shù)據(jù)實(shí)現(xiàn)更新后重新渲染頁(yè)面的方法
今天小編小編就為大家分享一篇Vue.js 通過(guò)jQuery ajax獲取數(shù)據(jù)實(shí)現(xiàn)更新后重新渲染頁(yè)面的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Elementui如何限制el-input框輸入小數(shù)點(diǎn)
這篇文章主要介紹了Elementui如何限制el-input框輸入小數(shù)點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
vue項(xiàng)目百度地圖如何自定義標(biāo)注marker
這篇文章主要介紹了vue項(xiàng)目百度地圖如何自定義標(biāo)注marker問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
vue2.0開發(fā)實(shí)踐總結(jié)之入門篇
這篇文章主要為大家總結(jié)了vue2.0開發(fā)實(shí)踐之入門,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12
axios模塊化封裝實(shí)例化及vue本地解決跨域方案
這篇文章主要為大家介紹了axios模塊化封裝實(shí)例化及vue本地解決跨域示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
Vue elementui字體圖標(biāo)顯示問(wèn)題解決方案
這篇文章主要介紹了Vue elementui字體圖標(biāo)顯示問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

