Vue3專欄項目 -- 二、自定義From組件(下)

需求分析:

現在我們還需要一個整體的表單在單擊某個按鈕的時候可以循環的驗證每個input的值,最后我們還需要有一個事件可以得到最后驗證的結果,從而進行下一步的操作

如下,我們應該有一個form表單包裹著全部的input表單;然后有一個提交按鈕;點擊這個按鈕觸發一個事件去驗證包裹的這些input,從而獲取驗證的結果。

這里有一個難點就是獲取每一個input的驗證結果。

一、ValidateForm編碼 - 使用插槽slot(實現所有input都在form表單中)

如下我們創建好了基本結構后

用插槽實現相對應樣式

我們是在該組件內添加自定義的內容,那么我們想到之前Dropdown下拉菜單欄組件的slot插槽,當時下拉菜單的‘新建文字’‘編輯資料’‘退出登錄’我們是怎么做的呢。我們建一個DropdownItem組件是一個新建文字的一個選項的組件,在該組件中用插槽占位,Dropdown也是用插槽占位,然后我們在GlobalHearder標題組件組件中想要多少個下拉選項就直接在DropdownItem中插入即可,插入的這些DropdownItem們就是插入到Dropdown的。如下,這種就可以想要多少個選項就直接在GlobalHearder中加入即可,這樣不限定DropdownItem插入多少也不限定Dropdown插入多少,插入多少都可以

但是和之前這個稍微不同的呢,是我們的插槽其實分為2塊區域,一塊是這個input表單,一塊是提交按鈕的區域,不傳任何內容的時候它會渲染一個默認的按鈕,就等于其實我們有兩個可以自定義的插槽,我們去文檔看看這種方法應該怎么實現,如下通過添加name的方式

如下我們就填入了兩個具名插槽

我們到App.vue中導入感受一下

如下我們使用一個叫template的元素,template上有一個屬性叫v-slot,這個v-slot指令就是組件內部定義的這個模板名稱,它就等于這個submit,那個name為submit的插槽。也可以用縮寫:#submit 也是一樣的

然后我們做點擊提交按鈕發送事件。

在子組件中點擊按鈕,點擊事件發送后,在父組件中監聽結果。

首先我們要在emit字段里面確定我們要發送的這個自定義事件的名稱,之前我們都是使用Object定義它,其實如果沒有這個事件的驗證,也可以使用數組來定義要觸發的事件,我們事件這里就叫form-submit

那么這個事件什么時候觸發呢,我們可以給這個submit-area上面添加一個click事件叫submitForm,然后這個點擊事件中通過context.emit('form-submit',true)來觸發它

然后我們到父組件中監聽結果。我們創建一個函數來監聽結果,如下定義一個函數叫onFormSubmit,然后在這個子組件標簽中通過@form-submit="onFormSubmit"即可

如下,我們定義一個onFromSubmit的函數,子組件那個點擊事件中觸發的就是父組件中這個事件,這個事件中我們打印一下獲取的參數。

如下,點擊按鈕后,控制臺打印出傳過來的值了

二、ValidateForm編碼 - 嘗試父子通訊(在form組件中獲取input組件中驗證方法返回的值)

現在我們來做在form中完成所有input的驗證。

要想在父組件中訪問子組件的方法,那么我們就必須拿到這個方法,并且調用,那么怎樣拿到一個組件的實例呢,就是說你怎么在父組件App.vue中拿到子組件ValidateInput.vue中的實例(實例即有這個子組件的所有屬性、方法)

我們之前獲取dom節點,使用了ref這個屬性,即在這個dom節點中添加這個ref。那么當這個ref屬性不是添加到一個節點上,而是添加到一個自定義組件上又會發生什么有趣的事呢。

如下,我們在父組件App.vue的setup中定義一個ref響應式的變量叫inputRef,然后在子組件validate-input的標簽中加上ref="inputRef",然后通過inputRef.val就可以獲取這個子組件validate-input的實例,我們在點擊事件即onFormSubmit中打印出這個實例

如下可以看到,這個Proxy對象中的這些屬性和方法都是子組件validateinput組件的屬性和方法,即我們成功獲得了子組件的實例對象。我們是想得到驗證的input的結果,也就是我們想在父組件中獲得validateInput組件中驗證表單的方法validateInput返回的結果,結果是驗證為true還是false。這種方法我們可以獲取子組件實例,也就是我們就可以獲得子組件某方法返回的結果。

如上,子組件驗證規則這個方法中返回驗證結果,然后我們在父組件中通過inputRef.value.validateInput()即可獲取到子組件中這個驗證方法,如此父組件中即可拿到子組件中驗證方法返回的結果了

那這種做法可以在validateForm中使用嗎,也就是說我們想在validateForm組件中也獲取validateInput組件的驗證方法的返回值。

來看validateForm的結構,這時候發現這里沒有validate-input標簽,變成了slot標簽,而這個slot占位符可能有多個validate-input,我們沒法用一個變量或者數組來定義它即像上面那樣定義一個響應式變量,而且slot也不支持ref屬性,那么就無法像上面那樣通過定義一個響應式變量,然后在標簽中通過ref="這個響應式變量",然后通過這個響應式變量.value來獲得這個validateInput組件的實例。

那怎么辦呢,那么這個通過ref獲取另一個組件實例的方法走不通了,我們就需要其他的一種父組件和子組件通訊方式。

由于slot的特殊性,這時候我們就需要事件監聽器來幫忙了。

我們在父組件validate-form中創建一個事件監聽器,去監聽相應的事件;然后在子組件validate-input中通過某種方法往這個監聽器里面手動觸發事件,把想要的內容傳遞過去

我們來想想應該怎么實現

首先我們應該在父組件即validateForm中創建事件監聽,也就是this.$on(事件名稱A,傳過來的函數)創建一個事件監聽,然后創建一個數組為空,該函數就把子組件傳過來的函數一個個放到數組中;

然后在子組件即validateItem中我們怎么拿到父組件這個事件呢,其實有一個神奇的屬性稱為$parent,這個$parent可以用來從一個子組件直接訪問父組件的實例,所以我們在子組件中通過this.$parent.emit('A',validateInput驗證函數),就可以實現在子組件中獲取父組件的事件監聽函數,同時把子組件的驗證函數發過去。

假如email這個item被初始化的時候,email的validateChange函數就會被加到數組中,password這個item被初始化的時候,password的validateChange函數就會被加到數組中,最后在父組件中循環調用這個方法就可以看到每個子組件的執行結果了

接下來我們編碼

由于this在setup中無法訪問,所以我們先用這個vue2方法創建,如下,發現說vue3中關于這個事件的這三個$on、$off、$once已經被放棄,推薦mitt

三、ValidateForm編碼 - 尋找外援mitt

可以看到mitt是一個流行的庫

如下可以看到它的API有如下

首先我們來安裝它 npm install --save mitt,然后在validate-form組件中引入這個mitt

然后我們到validate-form組件中創建一個事件監聽器,并且監聽相應的事件。

我們在它用法中可以看到我們直接調用mitt() 函數就可以創建監聽器了

所以如下創建監聽器mitt(),因為我們要把這個監聽器給validate使用,所以我們要把它導出去

然后現在是有了監聽器,然后我們定義監聽事件callback,然后我們通過emitter.on()把這個監聽事件添加到監聽器中,注意在組件銷毀階段記得把創建的監聽器銷毀

現在這個監聽器已經設置完畢,它像一個收音機一樣正在等待接收信號,現在讓我們到validateInput組件中向它發動信息

首先我們要把監聽器導入進validateInput組件中,然后在組件onmounted后就可以把信息發送出去了。

如下,我們在onmounted中向監聽器中發送東西了

如下,validateInput那邊onmounted中把inputRef.val值傳給名叫form-item-created的監聽器中了,監聽器監聽到有信息來了,就去觸發綁在它身上的這個callback函數并且把傳過來的inputRef.val值這個值傳給這個callback,該函數中打印出傳過來的值

所以如圖,控制臺中就打印出了validateInput中傳過來的輸入框的值

這就說明了我們在form中設立的電臺成功的收到了input的信號,那我們就成功在兩個組件中打通了溝通的橋梁,當然通過這種方法可以發送各種內容,而不僅僅是這個val字符串。

這樣我們就實現了子組件向父組件傳東西的想法,這樣下面子組件把驗證函數或者說驗證結果傳給父組件就行得通了

四、ValidateForm - 傳遞子組件的驗證函數給父組件

子組件向父組件發送子組件中真實的驗證函數。

所以validateInput組件中這里應該傳入validateInput函數

然后validateForm中應該接,首先我們定義一個空數組,用來放置子組件validateInput傳過來的驗證函數,這些函數執行以后可以顯示錯誤的信息并且返回input是否通過驗證,所以我們要給它一個簡單的定義,如下,定義一個類型ValidateFunc是一個函數,返回的是布爾值

然后最重要的一步,就是在這個submitForm即提交事件中,循環執行funcArr數組中傳過來的這些驗證函數,并且返回所有結果的最終值,并且最后通過這個事件發送出去。

循環調用一系列方法并且最終返回一個布爾,當有一個返回false,那么說明里面有錯誤,那么整個表單的驗證就沒有通過,那么就想到了用every方法。

但是當你用every()方法去執行funcArr數組中傳過來的這些驗證函數時,會發現如果輸入框都為空,點擊提交,發現只執行了一個驗證函數,即只有一個input框顯示出不能為空的提示。

這是因為類似every()、some() 這些Array上面的方法,它會提前停止循環,當我們里面有一個驗證函數返回false時,所以最終結果就是false,所以它很聰明就不再執行后面的函數就直接返回false了節省代碼執行時間,而這不是我們想要的,因為后面的驗證函數不執行的話,就無法彈出后面輸入框‘不能為空’的提示

所以我們需要運行數組里面的所有函數,然后再去判斷是否通過。這時候我們就把every改為map,改成map后會生成一個運行函數以后最終生成一個布爾數組,所以map(func=>func)就生成了一個裝滿布爾值的數組,然后我們再使用every就可以解決,every就去判斷這些布爾值中有沒有false即可

如下,得到所有input組件中的驗證函數后都存放在一個數組中,然后遍歷執行這個數組中的所有函數,然后得到所有input是否全部通過驗證的結果即result,最后這個result被傳回到了父組件App.vue中

這樣就實現了,form組件中獲取全部input組件的驗證結果,然后判斷出整個是否通過驗證,并且整個form組件是否通過驗證的結果還傳回了App.vue組件中

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

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

相關文章

Java面試八股之Java中的IO流分為幾種

Java中的IO流分為幾種 按數據單位分類: 字節流(Byte Stream):以字節(8位二進制數)為基本單位進行數據讀寫。字節流適合處理所有類型的數據,包括文本、圖像、音頻、視頻等二進制文件。抽象基類…

打破地域界限,HubSpot海外獲客系統引領企業走向國際化

在全球化的浪潮中,企業如何精準把握海外市場、高效獲取并轉化目標客戶,已成為決定其市場地位與未來發展的關鍵因素。HubSpot海外獲客系統以其獨特的視角、強大的功能和卓越的性能,正在引領全球營銷進入一個新的時代。今天運營壇將深入剖析Hub…

阿里巴巴找黃金寶箱(II) - 貪心思維

系列文章目錄 文章目錄 系列文章目錄前言一、題目描述二、輸出描述三、輸入描述四、java代碼五、測試用例 前言 本人最近再練習算法,所以會發布自己的解題思路,希望大家多指教 一、題目描述 一貧如洗的樵夫阿里巴巴在去砍柴的路上,無意中發…

KUKA機器人專業名詞解釋

1、CCU Cabinet Control Unit (控制柜控制單元) 2、CIB Cabinet Interface Board (控制柜接口板) 3、HMI Human Machine Interface (人機界面);KUKA.HMI 是 KUKA 操作界面。 4、KCB …

工作組PTH

文章目錄 簡述RID 500本地管理員密碼噴灑何為RIP 500 安全標識符SID與RIDPTH為何必須是RID 500CrackMapExec進行密碼噴灑 簡述 在工作組PTH中為什么只有administrator賬號可以,下面進行講解與利用。RID 500本地管理員密碼噴灑 何為RIP 500 安全標識符 安全標識符 安全標識符…

觸摸OpenNJet,云原生世界觸手可及

🌈個人主頁: Aileen_0v0 🔥熱門專欄: 華為鴻蒙系統學習|計算機網絡|數據結構與算法 ?💫個人格言:“沒有羅馬,那就自己創造羅馬~” 文章目錄 導言OpenNJet云原生引擎介紹云原生平臺的介紹優化與創新 為什么選擇OpenNJet云原生引擎如何在windo…

Pytorch基礎:torch.cuda.set_device函數

相關閱讀 Pytorch基礎https://blog.csdn.net/weixin_45791458/category_12457644.html?spm1001.2014.3001.5482 torch.cuda.set_device函數用于設置當前使用的cuda設備,在當擁有多個可用的GPU且能被pytorch識別的cuda設備情況下(環境變量CUDA_VISIBLE_…

【AI大模型】自動生成紅隊攻擊提示--GPTFUZZER

本篇參考論文為: Yu J, Lin X, Xing X. Gptfuzzer: Red teaming large language models with auto-generated jailbreak prompts[J]. arXiv preprint arXiv:2309.10253, 2023. https://arxiv.org/pdf/2309.10253 一 背景 雖然LLM在今天的各個領域得到了廣泛的運用…

計算方法實驗7:實現三次樣條插值算法

任務 point.txt文件中包含了21個壓鐵的位置信息 利用大M法計算出木條在壓鐵控制下的曲線,邊界條件取自然邊界條件;將第10個壓鐵的位置移動至(0,10),計算出新的曲線,觀察每個區間內的三次函數是否改變。 算法 μ i M i ? 1 2 …

MacOS java多版本安裝與管理

Home - SDKMAN! the Software Development Kit Manager # 安裝sdkman curl -s "https://get.sdkman.io" | bashsource "$HOME/.sdkman/bin/sdkman-init.sh"sdk version正常出現sdkman版本號就安裝成功了 # 安裝java # 安裝java8 sdk install java 8.0…

論文筆記:僅一個進程故障就無法達成共識

僅一個進程故障就無法達成共識 僅一個進程故障指的是在異步的分布式系統中 摘要 異步系統的共識問題(consensus)涉及一組進程,其中有的進程可能不可靠(unreliable)。共識問題要求可靠的進程一致地從兩個侯選中決定&…

【MATLAB源碼-第207期】基于matlab的單相光伏并網系統仿真,并網策略采用基于擾動觀測法的MPPT模型和使用電壓電流雙閉環SPWM控制。

操作環境: MATLAB 2022a 1、算法描述 本文將重點分析光伏發電最大功率點跟蹤(MPPT)技術和逆變器的并網控制技術,并在Simulink環境下建立模擬系統,以體現這些技術的應用與效果。文章結構如下:首先簡介光伏…

OpenAI下周發布更新;TikTok將自動標記AIGC;智譜AI亮相2024 ICLR

OpenAI 官宣下周舉辦直播發布更新 OpenAI 今日凌晨官宣,將在當地時間 5 月 13 日上午十點(北京時間 5 月 14 日凌晨兩點)在官網進行直播,屆時將演示一些 ChatGPT 和 GPT-4 的更新。 OpenAI CEO Sam Altman 補充表示,屆…

【算法刷題day44】Leetcode:518. 零錢兌換 II、377. 組合總和 Ⅳ

文章目錄 Leetcode 518. 零錢兌換 II解題思路代碼總結 Leetcode 377. 組合總和 Ⅳ解題思路代碼總結 草稿圖網站 java的Deque Leetcode 518. 零錢兌換 II 題目:518. 零錢兌換 II 解析:代碼隨想錄解析 解題思路 先遍歷物品,再遍歷背包。 代碼…

2024軟件測試面試必備面試題大全

1. 請自我介紹一下(需簡單清楚的表述自已的基本情況,在這過程中要展現出自信,對工作有激情,上進,好學) 面試官您好,我叫###,今年26歲,來自江西九江,就讀專業是電子商務,…

PCIE協議-2-事務層規范-MEM/IO/CFG request rules

2.2.7 內存、I/O和配置請求規則 以下規則適用于所有內存、I/O和配置請求。每種類型的請求還有特定的額外規則。 所有內存、I/O和配置請求除了常見的頭標字段外,還包括以下字段:requester ID[15:0]和Tag[9:0],形成事務ID。Last DW BE[3:0] a…

ICode國際青少年編程競賽- Python-2級訓練場-列表遍歷

ICode國際青少年編程競賽- Python-2級訓練場-列表遍歷 1、 for i in range(3):Flyer[i].step(2) Dev.step(6)2、 for i in range(7):Flyer[i].step() Dev.step(Item.x - Dev.x)3、 for i in range(3):Flyer[i].step(1) Dev.step(4) Dev.turnLeft() Dev.step(2) Dev.turnL…

【APM】在Kubernetes中搭建OpenTelemetry+Loki+Tempo+Grafana鏈路追蹤(一)

文章目錄 1、最終效果2、前提準備2、環境信息3、服務集成(Opentelemetry ->Tempo)3.1 上報鏈路數據3.1.1 下載opentelemetry-agent3.1.2 啟動配置業務app3.1.3 配置opentelemetry輸入輸出3.1.4 配置grafana datasource3.1.4.1 配置tempo3.1.4.2 配置l…

快速判斷出485從站設備是否支持MODBUS RTU無線通訊

對于變頻器和儀表設備,都支持485串口通訊,那么怎么判斷從站設備支持那種協議呢?通常分為兩種方式去判斷:1.從設備參數參看2.從設備通訊報文查看。本次文章以以臺達MH300系列變頻器為例。 1.從設備通訊參數查看 使用設備之前一定…

資料如何打印更省錢

在日常工作和學習中,我們經常需要打印各種資料。然而,隨著打印成本的不斷提高,如何更省錢地打印資料成為了大家關注的焦點。今天,就為大家分享一些資料打印的省錢技巧,并推薦一個省錢又省心的打印平臺。 首先&#xff…