vue3專欄項目 -- 六、上傳組件(上)

1、上傳組件需求分析

我們還需要新建和展示文章,新建文章自然是發送post請求,同時在post中自帶對應的數據,展示文章就是根據id取出已有的數據并且展示出來。

這里有一個難點就是上傳組件,上傳文件是App應用中最基本的需求,在Ajax出現之前,我們一般都使用一個簡單的input框來實現這個上傳的流程,把它的type設置成file,把from提交以后都交給后端處理。

自從有了ajax出現了以后,JS有了異步發送請求的能力,我們可以更方便的在頁面不跳轉的情況下完成文件的上傳,同時還能獲得很好的可視化效果,比如說傳的百分比、圖片的預覽、最終的狀態等等

整個流程,一開始我們應該有能力讓用戶去檢查這個圖片的格式或者大小的,我們會提供一個屬性叫beforeUpload,它是一個function,讓用戶去檢查這個文件的一些具體的需求;然后通過以后,這個時候這個組件就會向外反射一個uploading這樣一個事件;然后上傳成功以后就會觸發filrUploaded這個事件,或者出現錯誤就會觸發uploadedError這個事件。這些事件對于用戶來說非常重要,他們很需要知道這些事情是什么樣的時間發生的,然后可以做取得額外的工作,比如說beforeUploaded我們進行上傳前的檢查如文件類型/大小等等,或者在最終上傳失敗的時候我們可以彈出一些額外信息等等,這些都是事件給我們帶來的魔力,除了這些事件以外,自定義也是我們的一大看點,我們的用戶應該可以使用template來自定義一些顯示的內容,比如說我們一開始上傳區域長成什么樣可以是一大片也可以是一個button等,上傳中顯示什么圖標什么文字,上傳完畢以后要顯示什么樣的數據,這些我們應該是可以完全自定義的

通過流程這么分析,我們大致得出組件大致應該有些什么,如下

它應該有一個action,代表著我們要把這個請求發送到后端哪里去處理;然后應該有一個function即beforeUploaded去完成一些上傳前的校驗;之后就是3個要觸發的事件,uploading(點擊上傳按鈕后)、fileUploaded(上傳成功后)、uploadedError(上傳失敗后);除了這些我們還要支持自定義模板,默認就是一開始它長什么樣,我們這里是一個button,然后我們可以添加這個template,這個template分為uploaded的即上傳前的模板和loading的即上傳中的模板

發送異步請求是上傳組件的一個核心內容,那么接下來我們就談談使用axios來發送異步請求怎樣完成文件的上傳這個流程

2、上傳文件的兩種實現方式

接下來我們來了解上傳文件的原理

我們先從form提交的時候談起,既然要上傳文件,當然就要選擇文件,那么就可以選用如下

<input type="file">的標簽,這時候它就會渲染出一個可以選擇文件的對話框;那么當文件選擇完畢以后,我們有兩種方式上傳,一個是使用傳統的form submit即表單提交的方式;第二種是使用JavaScript發送異步請求的方式,這是我們著重要實現和理解的方法;

(1)如下我們了解一下第一種使用傳統的form submit即表單提交的方式的流程

如下例子,我們選擇文件然后點擊submit的時候它就會運行form的默認行為,帶input當中的數據,然后直接發送到一個特定的HTTP request請求到axios 的url,我們這里axios是/api/upload即會把input中的數據post到后端API為upload的地方中去,然后server端接到這個請求以后會做對應的處理,并且返回結果,這是一種典型的request到server的形式。這里要特別注意,我們這個表單一般于發送普通消息的表單,不同的地方就在于我們發送了文件,文件和普通的字符串不同,文件屬于一種二進制的格式,所以我們需要設置這個enctype="multipart/form-data",注意你要上傳文件或者你表單發送的有二進制的文件,那么就最好設置這種enctype="multipart/form-data"格式,因為表單的默認格式不支持二進制數據,所以需要設置成支持二進制數據的

我們選擇了文件后,點擊submit可以看到后端拿到這個內容以后就會做出對應的響應,它會返回如下圖片地址

我們的接口文檔中也提供了對應的接口

(2)使用JavaScript做file類型的表單上傳功能

了解了這些之后,我們就可以使用JavaScript來發送異步上傳文件的post請求了,提交form其實也就是發送http請求,那么使用JavaScript發送異步當然有更好的體驗了,其實它的過程也是萬變不離其宗的,也是用它來模擬表單的發送http請求

我們來新建文章頁面來嘗試一下,如下

然后我們嘗試一下上傳功能,如下我們點擊上傳某圖片后,上傳成功后它就打印出上傳成功的信息

從上面可以看到,使用JavaScript發送異步請求的方式和form提交的過程是非常相似的,只不過是用javascript模擬原生form的提交方式

3、Uploader組件 第一部分 -- 上傳組件流程

就和上面一樣,完成那個流程即可

(1)首先創建一個按鈕,使得點擊這個按鈕就執行file類型的input的點擊事件即彈出選擇文件的彈窗

如下,創建一個上傳組件叫Uploader.vue

復習一下:還記得怎么在setup中拿到一個dom節點嗎,通過ref咋拿來著,如下首先在標簽里通過加上ref="fileInput",然后const fileInput = ref<null | HTMLInputElement>(null),然后直接通過fileInput.value即可拿到這個fileInputDOM節點了

form那個方式是有一個input框,然后右邊有一個submit按鈕,我們想有一個按鈕,然后點擊這個按鈕就觸發file類型的input框,即想只展現出一個按鈕,這個按鈕的點擊事件中就觸發這個file input即form上傳功能。

怎么做,我們就如下設置一個button,也設置一個file類型的input,但是讓這個input隱藏即可,然后button的點擊事件中去獲取這個input的DOM節點,拿到input節點后接著去觸發input的點擊事件,即form中的那個submit的點擊事件(這個點擊事件就會去讓你挑選文件這樣子)。這樣就實現了頁面中展示一個點擊上傳的按鈕,然后你點擊這個按鈕,就會自動去觸發類型為file的input的點擊事件,從而就會展示出讓你選擇文件的彈窗

接下來我們來添加屬性

我們要接收一個action,這個action是接收發送請求的地址,而且是必選項是必須填的

(2)接下來就是上面說的經典的上傳過程

這里有個問題就是我們要根據不同的上傳階段,展示不同的元素,所以我們需要有一個字段來指示一下狀態如下,然后我們就開始做狀態變化后觸發的函數即handleFileChange函數

在這個函數中,我們做的就是如下獲取input這個DOM節點,這是為了我們在選擇文件的時候去獲取這個input的files屬性,因為我們選擇文件后這個input會帶上files屬性,這個屬性中就是我們選擇的那些文件們。我們獲取到我們選擇的文件后,首先去修改上傳的狀態,如下

這個e.target即事件對象就是這個input

我們選擇文件后,這個input就會加上這個files屬性,這個屬性即currenTarget.files打印出來可以看到就是我們選擇的那些文件,是一個列表list

然后繼續,獲取到我們選擇的文件后,我們把這個files變成一個Array,因為這個files是一個list并不是一個Array,我們用Array.form()來轉換成Array,是為了后面取它第一個。

然后創建一個form表單數據的屬性,怎么創建就通過new FormData() 從而創建一個Form表單數據屬性;然后把files的第一個數據給新建的這個FormData;FormData表單中有數據了,那么就可以進行post請求了,這個post請求中要傳三個參數,一個是url,一個是傳的數據,一個是headers(要寫成如下這個才可以接收二進制文件);最終處理請求的結果,通過.then() 接請求成功的結果然后進行如下處理,通過.catch() 接請求失敗的結果然后進行如下處理,最后那個finally是無論成功還是失敗都進行的函數,因為我們選擇了文件了嘛,所以input中的value被這個文件占了,你得先清空,下次再選擇時才不會出錯

(3)整個上傳流程總結:

我們的template中有button和file類型的input(給隱藏input),然后我們是通過點擊這個button去觸發該input的click點擊事件,這個點擊事件就會彈出讓你選擇文件的彈窗。

然后此時input在變化即change,說明此時在上傳文件,那么我們就給個change事件,這個事件是上傳的重點

在這個change事件中,我們要做的流程就是:獲取上傳的文件-->建表單數據-->發起請求,把選擇的文件傳給對應API

首先,獲取這個input這個dom節點(因為選擇文件后input會增加一個files屬性,這個屬性中就是我們選擇上傳的文件列表),獲取這個input就是為了獲取我們選擇上傳的文件

然后,拿到要上傳的文件后,新建一個表單數據屬性,并且給這個屬性files的值(因為post請求中要提交你選擇的文件嘛)

①把這個files列表變成Array即數組(這是為了獲取列表的第一個文件,我們只能選擇一個文件)

②新建一個form表單數據屬性,通過new FormData()

③把files中第一個文件數據給新建的這個FormData

最后,發起post請求,處理請求可能的請求成功、請求失敗的處理

至此文件已經可以成功上傳

過程中有一個小錯誤:

這里有一個要注意的點,就是發現在setup中說取不到props,要注意,setup(){}的括號中要寫上props才能取到props的值,有時候不小心漏了,setup函數,它接收兩個參數,一個是props,一個是context

4、Uploader組件 第二部分 -- 不同階段自定義操作

上面我們完成了上傳組件的最基本的流程,現在我們要將這里面的功能慢慢豐富進去

第一大功能就是在不同階段暴露出一系列的事件,對于用戶想在不同階段進行自定義操作的話就很有用;第二個是自定義模板,用戶可以根據需求渲染自己想要的頁面

(1)在上傳組件前,我們想自定義一個函數在上傳之前去檢查,比如上傳前檢查圖片是不是JGP格式,是JPG格式才能上傳

在上傳前我們想要有一些檢查的流程即beforeUpload函數,這個檢查是怎么檢查我們想要自定義式,怎么才能自定義呢,就你使用的地方定這個檢查邏輯,在這個上傳組件中只調用這個函數即可。

這個函數中應該接收用戶選擇的文件,然后經過一些列檢查,最終返回布爾值,布爾值代表著檢查的結果

如下在Uploader組件中

如下在Home.vue中,我們創建自定義檢查的這個beforeUpload函數,并且傳給uploader組件

即可如下,點擊上傳比如png的圖片,就會出現如下提示

(2)上傳成功后和上傳失敗后,我們想在這兩個時候做一些自定義的事情,則如下

如下,定義emits,emits中有file-uploaded表示上傳成功時調的函數、file-uploaded-error表示上傳失敗時調的函數,然后在上傳的post請求成功時通過context.emit()去調用對應的函數

從接口文檔中,我們可以看到返回的數據都是code、msg、data這樣的,所以我們到store中定義一個通用的格式,這樣就能享受到TypeScript類型的幫助,如下

然后我們在Home組件中定義這個上傳成功的函數以及上傳失敗的函數,如下

5、Uploader 組件第三部分 -- 自定義模板

(1)使用slot來做自定義模板

我們在Dropdown組件中我們已經見識過自定義模板,它是使用這個slot來完成這個對應功能的,讓我們來復習一下,我們使用name slot 來完成不同自定義模板的需求,我們在組件中添加slot,并且加上對應的name屬性,然后在使用的時候我們可以使用template標簽配合v-slot:name屬性來使用,這里面就是你自定義的HTML內容,v-slot也可以簡寫成一個#

現在要展示3個階段的界面,所以自然要展示三個slot來放置對應的自定義模板,所以如下我們來修改一下Uploader

如下,把正在上傳、上傳成功、點擊上傳都做成一個slot插槽,然后默認沒什么的時候它們就是一個個按鈕

然后如果這里面插入了東西,比如插入一段<h2>,那么就會替換這個插槽,但是這個h2標題還是有這個button這個按鈕功能,如下

插槽名為default時即展示h2的點擊上傳文本

插槽名為loading時,則展示這個旋轉圖標

上傳完畢后,我們需要在父組件Home.vue中拿到子組件Uploader.vue的一些數據,比如我們上傳完畢后想展示出這個圖片啥的,為了讓組件在slot中訪問子組件的某些特性,vue提供我們Scoped Slots就是為了讓我們解決這個問題的

(2)使用scoped slot 來解決子組件傳值給父組件的問題

看文檔,如下,子組件slot標簽中可以通過v-bind將一個屬性綁定到這個slot上面去,然后我們就可以給父組件中對應標簽中加上v-slot="xxx",然后通過xxx.這個屬性即可拿到這個屬性

如下,在Uploader組件中,我們新建一個ref屬性記錄請求成功時返回的數據,然后我們在slot中通過v-bind把這個數據傳出去,如下

然后到Home組件中使用,如下用v-slot接傳過來的值,把傳過來的值取名叫dataProps,然后在img中使用如下

如下,上傳成功后,圖片就展示出來了,這樣就實現了在slot中父組件使用子組件的數據的問題

6、改進路由驗證系統

接下來我們將上傳組件添加到新建文章頁面中,但是現在路由跳轉還有一些問題,我們先處理這個。

我們剛開始的路由驗證流程是如下這樣

但是我們發現了有一些問題,就是我們在下拉菜單組件點擊新建文章按鈕,可以正常跳轉到新建文章頁面,但是如果此時我們在新建文章頁面刷新就會發現會跳轉到登錄頁面,但是我們明明已經登錄了呀

這是因為路由中我們還是使用了store.state.user.isLogin來判斷的,而點擊刷新后store中的數據是都重置回初始值的。所以你登錄后isLogin確實從false置為true了,但是你刷新后isLogin就又是為false了,那么就符合這個if判斷了,所以就重定向到了登錄頁面去給你了

但是其實你此時是已經登錄狀態,而你用store.state.user.isLogin判斷就給你錯判成了未登錄狀態,所以首頁登錄過以后再點擊新建文章通過這個鏈接進行跳轉的話就不會有這個問題,這是我們要解決的問題,這里涉及稍微復雜的流程

所以我們要改進一下路由驗證系統,讓它更完善一些

我們做個流程圖,其實我們多的邏輯就是在發送請求這一步,其他的沒有什么區別,只不過現在的邏輯比以前復雜了一些

如下,一開始我們判斷這個user.isLogin,

如果已登錄是true,則判斷redirectAlreadyLogin這個參數存不存在,存在則跳轉到首頁,不存在則繼續進行;

如果未登錄是flase,那么我們就去判斷是否有token,

如果token不存在,則去判斷它訪問的這個路由是不是需要登錄才能訪問的,如果不是則繼續進行即讓他去這個路由的頁面,如果是需要登錄才能訪問的則跳轉到登錄頁面讓他先登錄;

(前面的和我們之前的一樣,我們新添加的邏輯就在這里)如果token存在,也就是說user的isLogin為false但是有token的情況,那么有可能是像上面這種剛剛刷新了isLogin為false但是其實是已登錄的狀態,也可能是有token但是是之前登錄的現在確實還沒有登錄,有token就說明這個用戶剛才或者之前登錄過,所以就直接重新發送一次異步fetchCurrentUser請求去登錄(這也是常見的,短時間內會自動登錄的嘛);然后就如果登錄失敗就彈出提示回到登錄頁面讓重新登錄,如果登錄成功則判斷是不是要到登錄或注冊頁面,如果是則重定向回首頁,如果不是比如是要到新建文章頁面那么直接next()即去新建文章頁面反正此時都登錄了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/12972.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/12972.shtml
英文地址,請注明出處:http://en.pswp.cn/web/12972.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Socks5:網絡世界的隱形斗篷

在數字化時代&#xff0c;網絡隱私和安全已成為人們日益關注的話題。Socks5&#xff0c;作為一種代理協議&#xff0c;為用戶在網絡世界中的匿名性提供了強有力的支持。本文將從Socks5的多個方面&#xff0c;深入探討這一技術如何成為網絡世界的“隱形斗篷”。 一、Socks5的基本…

linux基礎指令講解(ls、pwd、cd、touch、mkdir)

&#x1fa90;&#x1fa90;&#x1fa90;歡迎來到程序員餐廳&#x1f4ab;&#x1f4ab;&#x1f4ab; 主廚&#xff1a;邪王真眼 主廚的主頁&#xff1a;Chef‘s blog 所屬專欄&#xff1a;c大冒險 總有光環在隕落&#xff0c;總有新星在閃爍 這個是我們今天要用到的初始…

P8805 [藍橋杯 2022 國 B] 機房

P8805 [藍橋杯 2022 國 B] 機房 分析 是一道lca題目&#xff0c;可以直接套模板 前綴和處理點權 具體思路&#xff1a; 1.n臺電腦用n-1條網線相連&#xff0c;任意兩個節點之間有且僅有一條路徑&#xff08;拆分成各自到公共祖先節點的路徑——lca&#xff09;&#xff1b;…

Delphi7:SuperObject 的示例

SuperObject 不是一個 Delphi 7 自帶或官方的庫&#xff0c;但可能是指一些開源的 JSON 解析庫&#xff0c;比如 superobject 或 dwscript 中的 SuperObject。這些庫通常用于解析和生成 JSON 數據。 以下是一個基于假設的 SuperObject 用法概述&#xff0c;因為不同的庫可能有…

波搜索算法(WSA)-2024年SCI新算法-公式原理詳解與性能測評 Matlab代碼免費獲取

? 聲明&#xff1a;文章是從本人公眾號中復制而來&#xff0c;因此&#xff0c;想最新最快了解各類智能優化算法及其改進的朋友&#xff0c;可關注我的公眾號&#xff1a;強盛機器學習&#xff0c;不定期會有很多免費代碼分享~ 目錄 原理簡介 一、初始化階段 二、全…

我與C++的愛戀:string類的常見接口函數

? ? &#x1f525;個人主頁&#xff1a;guoguoqiang. &#x1f525;專欄&#xff1a;我與C的愛戀 朋友們大家好啊&#xff0c;本節我們來到STL內容的第一部分&#xff1a;string類接口函數的介紹 ? ? 1.string類的認識 給大家分享一個c文檔 https://legacy.cplusplus.…

Weblogic 管理控制臺未授權遠程命令執行漏洞(CVE-2020-14882,CVE-2020-14883)

1 漏洞概述 Weblogic Pre-Auth Remote Command Execution 漏洞&#xff08;CVE-2020-14882, CVE-2020-14883&#xff09;是針對 Oracle WebLogic Server 的兩個安全漏洞。CVE-2020-14882 允許遠程用戶繞過管理員控制臺組件中的身份驗證&#xff0c;而 CVE-2020-14883 則允許經…

Python3 筆記:Python的函數

函數是編寫好的&#xff0c;可重復調用的&#xff0c;用來實現某一功能的一段代碼。 也可以理解為做某事的方法和步驟。第一次做的時候寫好了方法&#xff0c;下次同類型的事直接拿來就用。 Python 內部有很多功能強大的內置函數供我們使用&#xff0c;除此之外&#xff0c;你…

Nagle算法

Nagle算法簡介 Nagle算法主要是避免發送小的數據包&#xff0c;要求TCP連接上最多只能有一個未被確認的小分組&#xff0c;在該分組的確認到達之前不能發送其他的小分組。 在默認的情況下,Nagle算法是默認開啟的&#xff0c;Nagle算法比較適用于發送方發送大批量的小數據&…

Sam Blackshear談Move語言的起源

Move編程語言作為Sui生態系統的關鍵組成部分&#xff0c;通過可編程交易區塊等機制支持其獨特的對象數據模型&#xff0c;并支持高效的代碼。五年前&#xff0c;Mysten Labs的聯合創始人兼首席技術官Sam Blackshear創建了Move。他專門設計了Move&#xff0c;用于編寫智能合約&a…

數據庫SQL查詢語句匯總詳解

SQL是一種強大的編程語句&#xff0c;可用于操作和提取數據庫中的數據。如果你對編程語句有所讓步&#xff0c;那么你可能對SQL的力量感到難以置信。本文將帶你深入探索SQL查詢的世界&#xff0c;讓你了解SQL語句的各種查詢方式&#xff0c;并以實例進行詳解。 1. SELECT基礎查…

Iterator底層源碼分析

/** * Iterator用于遍歷Collection下的集合&#xff0c;Collection下的每個集合底層實現不一樣&#xff0c;意味著遍歷邏輯也不一樣&#xff0c; * 所以Java的設計者將Iterator設計成了接口&#xff0c;讓Collection下的每個集合實現Iterator */ public interface Iterator<…

英偉達的GPU(1)

又好久沒更新了,一方面是最近事情有點多,另一方面最近也確實有點懶。 之前我說要把硬件部分補完,要寫Nvidia的GPU,我估計一篇寫不完,所以先寫點。 早先的硬件文章可以參考: 上一篇:解讀神秘的華為昇騰910 (qq.com) 上上一篇Microsoft Maia (qq.com) 上上上篇Google的…

sqli-labs靶場第十四關

目錄 1&#xff1a;分析 找閉合符&#xff1a; 2&#xff1a;開始注入 報錯注入&#xff1a; 注入數據庫名&#xff1a; 注入表名&#xff1a; 注入列名&#xff1a; 注入具體值&#xff1a; 1&#xff1a;分析 經過我們的實驗發現當我們輸入的密碼后面存在雙引號時會報…

【C++】學習筆記——多態_1

文章目錄 十二、繼承8. 繼承和組合 十三、多態1. 多態的概念2. 多態的定義和實現虛函數重寫的兩個特殊情況override 和 ?nal 3. 多態的原理1. 虛函數表 未完待續 十二、繼承 8. 繼承和組合 我們已經知道了什么是繼承&#xff0c;那組合又是什么&#xff1f;下面這種情況就是…

英語學習筆記13——A new dress

A new dress 一件新連衣裙 詞匯 Vocabulary colour / color n. 顏色 v. 上色&#xff0c;涂色  英  美 顏色短語&#xff1a;green hand 新手      black tea 紅茶      white house 白宮      black sheep 害群之馬 英文顏色類詞匯&#xff1a; red 紅色…

鴻蒙開發接口Ability框架:【ApplicationContext】

ApplicationContext ApplicationContext模塊提供開發者應用級別的的上下文的能力&#xff0c;包括提供注冊及取消注冊應用內組件生命周期的監聽接口。 說明&#xff1a; 開發前請熟悉鴻蒙開發指導文檔&#xff1a; gitee.com/li-shizhen-skin/harmony-os/blob/master/README.m…

靜態IP代理:網絡世界的隱秘通道

在數字化時代&#xff0c;網絡安全和隱私保護日益受到重視。靜態IP代理作為一種網絡服務&#xff0c;為用戶提供了一個穩定且可預測的網絡連接方式&#xff0c;同時保護了用戶的在線身份。本文將從五個方面深入探討靜態IP代理的概念、優勢、應用場景、技術實現以及選擇時的考量…

C語言學習【printf函數和scanf函數】

C語言學習【printf函數和scanf函數】 printf()函數和scanf()函數可以讓用戶與程序交流&#xff0c;是輸入/輸出函數 printf()函數 請求printf()函數打印數據的指令要與待打印數據的類型相匹配。例如&#xff0c;打印整數時使用%d&#xff0c;打印字符時使用%c。這些符號被稱…

實戰項目技術點(1)

1、什么是REST&#xff1f; REST&#xff08;Representational State Transfer&#xff09;&#xff0c;表述性狀態轉換&#xff0c;它是一種軟件架構風格。傳統URL風格如下&#xff1a; http://localhost:8080/user/getById?id1 GET&#xff1a;查詢id為1的用戶 http://loc…