<td id="aqqih"></td>

<dd id="aqqih"></dd>
  1. <span id="aqqih"></span>
  2. <ol id="aqqih"></ol>

    怎么使用vue實現上傳組件

    今天小編給大家分享一下怎么使用vue實現上傳組件的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    思路

    文件上傳的兩種實現方式

    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接口

    生命周期

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

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

    代碼草稿

    本例中采用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
    ????})
    ??}
    }

    具體實現

    //?Upload.vue
    <template>
    ??<div>
    ????<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"?class="file-input?d-none"?name="file"?ref="uploadInput"?@change="hanldeInput"/>
    ??</div>
    </template>
    <script>
    import?{?defineComponent,?ref,?PropType,?watch?}?from?'vue'
    import?axios?from?'axios'
    type?UploadStatus?=?'ready'?|?'loading'?|?'success'?|?'error'
    type?FunctionProps?=?(file:File)?=>?boolean
    export?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])?:?true
    ????????if?(!validateFormat)?return
    ????????fileStatus.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>
    ????<upload
    ??????action="/upload"
    ??????:beforeUpload="beforeUpload"
    ??????:uploadedData="uploadedData"
    ??????@file-uploaded-success="hanldeUploadSuccess"
    ??????class="d-flex?align-items-center?justify-content-center?bg-light?text-secondary?w-100?my-4"
    ??????>
    ??????<template?#uploaded="slotProps">
    ????????<div>
    ??????????<img?:src="slotProps.uploadedData.data.url"/>
    ??????????<h4>點擊重新上傳</h4>
    ????????</div>
    ???????</template>
    ???????<template?#default>
    ?????????<h3>點擊上傳頭圖</h3>
    ???????</template>
    ???????<template?#loading>
    ?????????<div>
    ??????????<div?class="spinner-border?text-secondary"?role="status">
    ????????????<span></span>
    ??????????</div>
    ?????????</div>
    ???????</template>
    ????</upload>
    ??</div>
    </template>
    <script>
    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?h4{
    ??display:?block;
    }
    .uploaded-area?h4{
    ??display:?none;
    ??position:?absolute;
    ??color:?#999;
    ??text-align:?center;
    ??width:?100%;
    ??top:50%
    }
    </style>

    以上就是“怎么使用vue實現上傳組件”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注蝸牛博客行業資訊頻道。

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:niceseo99@gmail.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    評論

    日本韩欧美一级A片在线观看
    <td id="aqqih"></td>

    <dd id="aqqih"></dd>
    1. <span id="aqqih"></span>
    2. <ol id="aqqih"></ol>