电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

vue 實現上傳組件

瀏覽:16日期:2022-09-29 10:03:44
目錄1.介紹2.思路文件上傳的兩種實現方式3.生命周期4.代碼草稿5.具體實現1.介紹

效果如下圖

vue 實現上傳組件

2.思路文件上傳的兩種實現方式

1.From形式

<form method='post' enctype='multipart/from-data' action='api/upload'> <input type='file name='file'> <button type='submit'>Submit</button></form>

form的method屬性指定為 'post' 請求,通過HTML表單發送數據給服務器,并返回服務器的修改結果,在這種情況下Content-Type是通過在<form>元素中設置正確的enctype屬性。

form的enctype屬性規定在發送到服務器之前應該如何對表單數據進行編碼。

application/x-www-form-urlencoded(默認值):表示在發送前編碼所有字符,數據被編碼成以'&'分隔的鍵值對,同時以'='分隔鍵和值,('name=seven&age=19')。不支持二進制數據。 multipart/form-data:支持二進制數據(上傳文件時必須指定)

2.JavaScript異步請求形式

我們知道 FormData 接口提供了一種表示表單數據的鍵值對 key/value 的構造方式,并且可以輕松的將數據通過XMLHttpRequest.send()方法發送出去,本接口和此方法都相當簡單直接。如果送出時的編碼類型被設為 'multipart/form-data',它會使用和表單一樣的格式。

var formdata = new FormData(); // 創建FormData對象formdata.append('name','laotie'); // 通過append()方法添加新的屬性值... // 更多方法請點下面鏈接

FormData接口

3.生命周期

上傳組件也有它的生命周期

beforeUpload --> uploading --> fileUploaded 或者 uploadedError

4.代碼草稿

本例中采用js異步請求的方式開發上傳組件

<input type='file' name='file' @change.prevent='handleFileChange'>// 創建一個file類型的input,用于觸發文件上傳,后面可以把input隱藏掉,自定義好看的樣式// 自定義樣式的時候可以用slot區分不同上傳狀態的樣式(loading,success,defult)

const handleFileChange = (e:Event)=>{ const target = e.target as HTMLInputElement const files = Array.from(target.files)// 注意這里取得的是一個類數組 if(files){ // 取得文件 const uploadedFile = files[0]if(!validateFormat) return // ...這里只是提供一種思路,具體校驗不再講述 // 在這里做一些上傳文件前的校驗,比如文件格式,大小等, // 不符合要求的話就不在繼續發送請求const formData = new FormData() formData.append(uploadedFile.name,uploadedFile)axios.post(’/upload’,formData,{ headers:{ // 注意設置編碼類型’Content-Type’: ’multipart/form-data’ } }).then(res=>{ console.log(’上傳成功’) }).catch(error =>{ // 文件上傳失敗 }).finally(()=>{ // 文件上傳完成,無論成功還是失敗 // 這里可以清除一下input.value }) }}5.具體實現

// Upload.vue<template> <div class='upload-container'> <div @click.prevent='triggerUpload' v-bind='$attrs'> <slot name='loading' v-if='fileStatus===’loading’'><button class='btn btn-primary'>上傳中</button> </slot> <slot name='uploaded' v-else-if='fileStatus===’success’' :uploadedData='fileData'><button class='btn btn-primary'>上傳成功</button> </slot> <slot v-else name='default'><button class='btn btn-primary'>點擊上傳</button> </slot> </div> <input type='file' name='file' ref='uploadInput' @change='hanldeInput'/> </div></template><script lang='ts'>import { defineComponent, ref, PropType, watch } from ’vue’import axios from ’axios’type UploadStatus = ’ready’ | ’loading’ | ’success’ | ’error’type FunctionProps = (file:File) => booleanexport default defineComponent({ name: ’Upload’, inheritAttrs: false, props: { // 上傳的url action: { type: String, required: true }, // 上傳之前的校驗,是一個返回布爾值的函數 beforeUpload: { type: Function as PropType<FunctionProps> }, // 上傳好的數據,用來判斷狀態或做初始化展示 uploadedData: { type: Object } }, emits: [’file-uploaded-success’, ’file-uploaded-error’], setup(props, ctx) { const uploadInput = ref<null | HTMLInputElement>(null) const fileStatus = ref<UploadStatus>(props.uploadedData ? ’success’ : ’ready’) const fileData = ref(props.uploadedData) watch(() => props.uploadedData, (val) => { if (val) {fileStatus.value = ’success’fileData.value = val } }) const triggerUpload = () => { if (uploadInput.value) {uploadInput.value.click() } } const hanldeInput = (e:Event) => { const target = e.target as HTMLInputElement const files = target.files console.log(target) if (files) {const uploadFile = Array.from(files)const validateFormat = props.beforeUpload ? props.beforeUpload(uploadFile[0]) : trueif (!validateFormat) returnfileStatus.value = ’loading’const formData = new FormData()formData.append(’file’, uploadFile[0])axios.post(props.action, formData, { headers: { ’Content-Type’: ’multipart/form-data’ }}).then(res => { console.log(’文件上傳成功’, res) fileStatus.value = ’success’ fileData.value = res.data ctx.emit(’file-uploaded-success’, res.data)}).catch(error => { console.log(’文件上傳失敗’, error) fileStatus.value = ’error’ ctx.emit(’file-uploaded-error’, error)}).finally(() => { console.log(’文件上傳完成’) if (uploadInput.value) { uploadInput.value.value = ’’ }}) } } return { uploadInput, triggerUpload, hanldeInput, fileStatus, fileData } }})</script>

使用示例:

<template> <div class='create-post-page'> <upload action='/upload' :beforeUpload='beforeUpload' :uploadedData='uploadedData' @file-uploaded-success='hanldeUploadSuccess' > <template #uploaded='slotProps'><div class='uploaded-area'> <img :src='http://www.hdgsjgj.cn/bcjs/slotProps.uploadedData.data.url'/> <h3>點擊重新上傳</h3></div> </template> <template #default> <h2>點擊上傳頭圖</h2> </template> <template #loading> <div class='d-flex'> <div role='status'> <span class='sr-only'></span> </div> </div> </template> </upload> </div></template><script lang='ts'>import { defineComponent, ref, onMounted } from ’vue’import Upload from ’../components/Upload.vue’import createMessage from ’../components/createMessage’export default defineComponent({ name: ’CreatePost’, components: { Upload }, setup() { const uploadedData = ref() //創建一個響應式數據 let imageId = ’’ onMounted(() => { .... // 這里有邏輯省略了,取到初始化數據image if (image) {uploadedData.value = { data: image } } }) // 上傳前校驗,返回布爾值 const beforeUpload = (file:File) => { const res = beforeUploadCheck(file, {format: [’image/jpeg’, ’image/png’],size: 1 }) const { error, passed } = res if (error === ’format’) {createMessage(’上傳圖片只能是JPG/PNG格式!’, ’error’) } if (error === ’size’) {createMessage(’上傳圖片大小不能超過1MB’, ’error’) } return passed } // 上傳成功后拿到imageId就可以進行后續處理,創建表單啥的 const hanldeUploadSuccess = (res:ResponeseProps<ImageProps>) => { createMessage(`上傳圖片ID ${res.data._id}`, ’success’) if (res.data._id) {imageId = res.data._id } } return { beforeUpload, hanldeUploadSuccess, uploadedData } }})</script><style>.create-post-page{ padding:0 20px 20px;}.create-post-page .upload-box{ height:200px; cursor: pointer; overflow: hidden;}.create-post-page .upload-box img{ width: 100%; height: 100%; object-fit: cover;}.uploaded-area{ position: relative;}.uploaded-area:hover h3{ display: block;}.uploaded-area h3{ display: none; position: absolute; color: #999; text-align: center; width: 100%; top:50%}</style>

以上就是vue 實現上傳組件的詳細內容,更多關于vue 上傳組件的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
主站蜘蛛池模板: 天津蒸汽/热水锅炉-电锅炉安装维修直销厂家-天津鑫淼暖通设备有限公司 | 武汉印刷厂-不干胶标签印刷厂-武汉不干胶印刷-武汉标签印刷厂-武汉标签制作 - 善进特种标签印刷厂 | 留学生辅导网-在线课程论文辅导-留学生挂科申诉机构 | 磁粉制动器|张力控制器|气胀轴|伺服纠偏控制器整套厂家--台灵机电官网 | 北京办公室装修,办公室设计,写字楼装修-北京金视觉装饰工程公司 北京成考网-北京成人高考网 | 橡胶粉碎机_橡胶磨粉机_轮胎粉碎机_轮胎磨粉机-河南鼎聚重工机械制造有限公司 | 罗氏牛血清白蛋白,罗氏己糖激酶-上海嵘崴达实业有限公司 | 课件导航网_ppt课件_课件模板_课件下载_最新课件资源分享发布平台 | 石英陶瓷,石英坩埚,二氧化硅陶瓷-淄博百特高新材料有限公司 | 自清洗过滤器,浅层砂过滤器,叠片过滤器厂家-新乡市宇清净化 | 广州监控安装公司_远程监控_安防弱电工程_无线wifi覆盖_泉威安防科技 | 消电检公司,消电检价格,北京消电检报告-北京设施检测公司-亿杰(北京)消防工程有限公司 | 耳模扫描仪-定制耳机设计软件-DLP打印机-asiga打印机-fitshape「飞特西普」 | 变压器配件,变压器吸湿器,武强县吉口变压器配件有限公司 | 电动不锈钢套筒阀-球面偏置气动钟阀-三通换向阀止回阀-永嘉鸿宇阀门有限公司 | 膜片万向弹性联轴器-冲压铸造模具「沧州昌运模具」 | 保温杯,儿童婴童奶瓶,运动水壶「广告礼品杯定制厂家」超朗保温杯壶 | 东莞画册设计_logo/vi设计_品牌包装设计 - 华略品牌设计公司 | 冷却塔改造厂家_不锈钢冷却塔_玻璃钢冷却塔改造维修-广东特菱节能空调设备有限公司 | 杭州实验室尾气处理_实验台_实验室家具_杭州秋叶实验设备有限公司 | 单螺旋速冻机-双螺旋-流态化-隧道式-食品速冻机厂家-广州冰泉制冷 | 深圳湾1号房价_深圳湾1号二手房源| 广州二手电缆线回收,旧电缆回收,广州铜线回收-广东益福电缆线回收公司 | 高低温试验房-深圳高低温湿热箱-小型高低温冲击试验箱-爱佩试验设备 | 泡沫消防车_水罐消防车_湖北江南专用特种汽车有限公司 | 丁基胶边来料加工,医用活塞边角料加工,异戊二烯橡胶边来料加工-河北盛唐橡胶制品有限公司 | 京马网,京马建站,网站定制,营销型网站建设,东莞建站,东莞网站建设-首页-京马网 | 阜阳在线-阜阳综合门户 | 硫化罐_蒸汽硫化罐_大型硫化罐-山东鑫泰鑫智能装备有限公司 | 常州翔天实验仪器厂-恒温振荡器-台式恒温振荡器-微量血液离心机 恒温恒湿箱(药品/保健品/食品/半导体/细菌)-兰贝石(北京)科技有限公司 | 聚氨酯复合板保温板厂家_廊坊华宇创新科技有限公司 | 定时排水阀/排气阀-仪表三通旋塞阀-直角式脉冲电磁阀-永嘉良科阀门有限公司 | 自动部分收集器,进口无油隔膜真空泵,SPME固相微萃取头-上海楚定分析仪器有限公司 | 丹佛斯变频器-Danfoss战略代理经销商-上海津信变频器有限公司 | 东莞螺丝|东莞螺丝厂|东莞不锈钢螺丝|东莞组合螺丝|东莞精密螺丝厂家-东莞利浩五金专业紧固件厂家 | 智能交通网_智能交通系统_ITS_交通监控_卫星导航_智能交通行业 | 印刷人才网 印刷、包装、造纸,中国80%的印刷企业人才招聘选印刷人才网! | 车牌识别道闸_停车场收费系统_人脸识别考勤机_速通门闸机_充电桩厂家_中全清茂官网 | 创绿家招商加盟网-除甲醛加盟-甲醛治理加盟-室内除甲醛加盟-创绿家招商官网 | 转子泵_凸轮泵_凸轮转子泵厂家-青岛罗德通用机械设备有限公司 | 成都亚克力制品,PVC板,双色板雕刻加工,亚克力门牌,亚克力标牌,水晶字雕刻制作-零贰捌广告 |