Vue動(dòng)態(tài)組件之表單的CURD

我在Vue動(dòng)態(tài)組件上的坑上重復(fù)踩了兩次,一模一樣的兩次思考過(guò)程。

我想,這個(gè)重復(fù)思考的過(guò)程并不是偶然,說(shuō)明是很有必要討論一下這個(gè)問(wèn)題的。

那么為了這個(gè)意義,我來(lái)說(shuō)一下最近遇到的問(wèn)題,有關(guān)于『 Vue動(dòng)態(tài)組件 』的問(wèn)題。

由于本人平時(shí)經(jīng)常做的事就是操作表單,Vue的數(shù)據(jù)綁定和樣式綁定等特別適合我現(xiàn)在的開發(fā)模式。但是表單常出現(xiàn)的CURD,就不是簡(jiǎn)單的雙向綁定那么簡(jiǎn)單的操作了。

首先對(duì)想要實(shí)現(xiàn)的功能進(jìn)行簡(jiǎn)短的描述:由于模板數(shù)據(jù)的Keyword是動(dòng)態(tài)添加的,需要寫一條就增加一條keyword記錄并輸出,而輸出的keyword需要可以進(jìn)行修改和刪除操作;在進(jìn)行修改操作的時(shí)候,選中的記錄會(huì)綁定到輸入框中,在輸入框中進(jìn)行修改后,能實(shí)現(xiàn)雙向綁定到列表中的數(shù)據(jù)上;刪除操作,就是刪除當(dāng)前選中的記錄;最后點(diǎn)擊提交的時(shí)候要能夠把所有的keyword的作為一個(gè)數(shù)組,添加到目標(biāo)對(duì)象中去。

這是最簡(jiǎn)單不過(guò)的增刪查改,用jQuery來(lái)解決的時(shí)候,考驗(yàn)的就是對(duì)數(shù)組結(jié)構(gòu)的操作。但是如果要把他寫成組件,將面臨『動(dòng)態(tài)組件』的問(wèn)題。

我一開始思考這個(gè)問(wèn)題的時(shí)候,并不是打算將所有的keyword作為一個(gè)列表輸出,然后在列表上進(jìn)行修改和刪除操作。而是打算只要點(diǎn)擊“添加關(guān)鍵字”,就動(dòng)態(tài)插入輸入框,并為每個(gè)輸入框綁定v-model,這樣就能夠?qū)崿F(xiàn)實(shí)時(shí)的刪除和修改操作。

--------------------!!!然而這樣的思路是錯(cuò)誤的!!!--------------------

因?yàn)樗悸肥清e(cuò)誤的,所以按照錯(cuò)誤的思路,第一步想要實(shí)現(xiàn)的就是動(dòng)態(tài)生成組件。?

這是html部分, 在父級(jí),主要是一個(gè)div用來(lái)插入組件,一個(gè)button用來(lái)觸發(fā)插入事件。

在組件部分,主要是一個(gè)header用來(lái)觸發(fā)一個(gè)測(cè)試點(diǎn)擊事件,用來(lái)測(cè)試是否能夠調(diào)用組件的methods,并且有一個(gè)img標(biāo)簽,用來(lái)測(cè)試是否能夠讀取構(gòu)造組件時(shí)候的data。

這是js部分,先是創(chuàng)建了一個(gè)組件about的構(gòu)造器,它對(duì)應(yīng)的組件id是html中的#about,構(gòu)造組件的data只能是一個(gè)function,真正的data可以作為一個(gè)對(duì)象寫在function的return中。我們現(xiàn)在構(gòu)造的這個(gè)about組件中的data返回的是一個(gè)img的src,它的methods是點(diǎn)擊之后log。

在model中注冊(cè)了組件about,使用構(gòu)造函數(shù)new了一個(gè)about。并將new出來(lái)的about組件手動(dòng)掛載($mount)到model實(shí)例中去,然后再在相應(yīng)的dom結(jié)構(gòu)(#main)中插入($appendTo)組件。這樣每次點(diǎn)擊“添加組件”按鈕的時(shí)候就能夠,新注冊(cè)一個(gè)about組件,并手動(dòng)掛載后插入。

這樣就實(shí)現(xiàn)動(dòng)態(tài)生成組件,但是這樣生成的組件只是簡(jiǎn)單的進(jìn)行數(shù)據(jù)渲染,而并不存在表單操作。所以離一開始我的錯(cuò)誤思路只差一步,那就是給插入的組件進(jìn)行雙向綁定。

這里順便一提,對(duì)于上傳到七牛上的圖片文件的在線鏈接,能夠利用在鏈接后面增加參數(shù),達(dá)到壓縮圖片的效果。如上圖,關(guān)鍵字就是『 ?imageView2/1 』,之后的參數(shù)『w』『h』和『q』是設(shè)置寬、高和圖片質(zhì)量的參數(shù)。

這就是實(shí)現(xiàn)的效果,一開始只有一個(gè)按鈕,點(diǎn)擊按鈕之后,動(dòng)態(tài)插入了組件about。

利用extend 、$mount、 $appendTo實(shí)現(xiàn)了動(dòng)態(tài)插入組件,之后我又新建了一個(gè)demo用于實(shí)現(xiàn)動(dòng)態(tài)組件的雙向綁定。

先上一下效果圖,然后就會(huì)知道這樣做的思路是多么的愚蠢。

輸入框中的內(nèi)容純粹是為了測(cè)試用,下同~

第一步,頁(yè)面自帶一個(gè)原始的表單,表單包括兩個(gè)項(xiàng)目,學(xué)校名稱和學(xué)校網(wǎng)址。這個(gè)表單綁定的是我的數(shù)組對(duì)象的第0個(gè)元素。

第二步,當(dāng)我點(diǎn)擊“添加組件”按鈕之后,我會(huì)動(dòng)態(tài)插入一個(gè)表單,在數(shù)組對(duì)象中push一個(gè)空對(duì)象,并log出我的對(duì)象。

我插入的表單組件中的項(xiàng)目依然是學(xué)校名稱和學(xué)校網(wǎng)址,并且我讓插入的表單組件的輸入框綁定我數(shù)組的第(length-1)個(gè)元素。這樣我在輸入框中進(jìn)行的數(shù)據(jù)操作能夠通過(guò)雙向綁定寫入目標(biāo)對(duì)象。在這一步,我在輸入框輸入的是“集美大學(xué)”和"www.hao123.com"。到這里看上去似乎一切都是正常的,接下來(lái),肯定會(huì)需要再次進(jìn)行push操作。

第三步,再次點(diǎn)擊“添加組件”按鈕之后,依然是動(dòng)態(tài)插入了一個(gè)數(shù)組,并且數(shù)組對(duì)象中push了一個(gè)空對(duì)象。數(shù)組長(zhǎng)度為3。

我們可以從控制臺(tái)看出,我的數(shù)組對(duì)象是正確的。第0個(gè)元素是“廈門大學(xué)”,第1個(gè)元素是“集美大學(xué)”。值得一提的是由于log的操作是在點(diǎn)擊“添加組件”,然后插入空對(duì)象之后觸發(fā)的,所以我現(xiàn)在新輸入的數(shù)組的第三個(gè)元素“123”并沒(méi)有在控制臺(tái)中輸出,但是我只要在輸入框中進(jìn)行數(shù)據(jù)操作,實(shí)際上它是寫入目標(biāo)數(shù)組的,并不是數(shù)組對(duì)象的第3個(gè)元素沒(méi)有寫入。

同時(shí),注意頁(yè)面上動(dòng)態(tài)組件的變化,當(dāng)我在第三個(gè)表單中填寫“123”和“456”的時(shí)候,第二個(gè)表單的內(nèi)容也發(fā)生的相應(yīng)的變化,一方面說(shuō)明,我的雙向綁定是有成功寫入目標(biāo)數(shù)組的,另一方面,說(shuō)明表單組件的輸入框如果綁定的是第(length-1)個(gè)的數(shù)組元素的話,length的值也是隨著數(shù)組變化而變化的。所以會(huì)出現(xiàn)第二個(gè)表單的內(nèi)容會(huì)跟隨我在第三個(gè)表單的輸入框中的輸入值進(jìn)行動(dòng)態(tài)變化。

這里會(huì)有幾個(gè)疑問(wèn):

1.有人會(huì)認(rèn)為,【反正提交給后臺(tái)的數(shù)組是正確的不就好了嗎】,那么要做到這樣的前提就是【每一次的操作都是準(zhǔn)確無(wú)誤的操作】。因?yàn)楝F(xiàn)在這樣,已經(jīng)無(wú)法做到刪除和修改。

2.有人會(huì)認(rèn)為,【只要每次給輸入框綁定事先經(jīng)過(guò)計(jì)算的(length-1)的結(jié)果不就好了嗎】,那么為了這個(gè)要求,需要重新構(gòu)造對(duì)象的屬性。這個(gè)對(duì)象會(huì)在原來(lái)的“學(xué)校名稱”和“學(xué)校網(wǎng)址”的基礎(chǔ)上再多一個(gè)屬性比如叫“currentLength”,專門用來(lái)記錄創(chuàng)建對(duì)象那個(gè)時(shí)刻的(length-1)的結(jié)果,比如“集美大學(xué)”的兄弟屬性“currentLength”就應(yīng)該為1,“123”的兄弟屬性“currentLength”就應(yīng)該為2。但是我在傳json給后臺(tái)的時(shí)候,并不需要這個(gè)“currentLength”,那么又要重新創(chuàng)建一個(gè)對(duì)象。這樣就失去雙向綁定可以不用構(gòu)造對(duì)象的意義了。

3.有人會(huì)認(rèn)為,【可能會(huì)需要一個(gè)提交當(dāng)前表單的操作】,這個(gè)是沒(méi)有必要的操作,因?yàn)殡p向綁定,本身就是動(dòng)態(tài)寫入的。只要你在綁定的輸入框中輸入相應(yīng)的數(shù)據(jù),原先的數(shù)組對(duì)象的元素都會(huì)改變的。

我們來(lái)看下這個(gè)實(shí)現(xiàn)動(dòng)態(tài)綁定組件的代碼吧~

這是html的代碼,父級(jí)#main中本身就有一個(gè)section存放表單,表單的輸入框綁定的是目標(biāo)對(duì)象companies的第0個(gè)元素。組件部分綁定的是目標(biāo)對(duì)象的第(length-1)個(gè)對(duì)象。

這是js的代碼,構(gòu)建組件的data的時(shí)候,要先讓companies從model實(shí)例中傳過(guò)來(lái),用一個(gè)新的對(duì)象com來(lái)存。在父級(jí)#main的button觸發(fā)了點(diǎn)擊事件之后,先push了一個(gè)空對(duì)象,然后用之前的$mount進(jìn)行手動(dòng)掛載,最后打印當(dāng)前數(shù)組。

思考這個(gè)問(wèn)題,思考了好幾個(gè)小時(shí),連次晚飯的時(shí)候都在想?。。?!依稀記得那天吃的西北拉面。就連跟柯哲吃飯的時(shí)候,柯哲問(wèn)我,”明天學(xué)校的考試是最后一科嗎“,我都懶得回答,只是點(diǎn)了個(gè)頭。我想,柯哲當(dāng)時(shí)肯定心想(′???`) “這個(gè)傻×”

--------------------!!!然而接下來(lái)的思路是正確的!!!--------------------

發(fā)現(xiàn)不能利用動(dòng)態(tài)組件來(lái)解決表單的問(wèn)題,所以就換一個(gè)思路,固定一個(gè)表單,而不需要?jiǎng)討B(tài)添加表單。另外設(shè)置一個(gè)表單顯示目標(biāo)數(shù)組,然后把需要進(jìn)行操作的對(duì)象綁定到那個(gè)固定的表單中去。

話不多說(shuō),舉一個(gè)例子,<動(dòng)態(tài)添加單項(xiàng)選擇題的選項(xiàng)> ,先上效果圖。

我在第一個(gè)紅框中輸入我要錄入的信息,點(diǎn)擊“添加一個(gè)選項(xiàng)”按鈕,然后能夠第二個(gè)紅框中進(jìn)行動(dòng)態(tài)渲染我的目標(biāo)對(duì)象中的每一個(gè)元素。在點(diǎn)擊“修改”按鈕后,能夠?qū)Ⅻc(diǎn)擊的這個(gè)元素動(dòng)態(tài)渲染到第一個(gè)紅框中的表單中,這樣就能夠通過(guò)輸入框進(jìn)行實(shí)時(shí)更新數(shù)據(jù)操作。在點(diǎn)擊“刪除”按鈕后,能夠刪除當(dāng)前元素。需要明確的一點(diǎn)就是,第二個(gè)紅框中的列表顯示的每一個(gè)框,就是我【當(dāng)前目標(biāo)數(shù)組中的實(shí)時(shí)元素】。

如圖,我先添加了B和C兩個(gè)選項(xiàng)。具體的操作就是在輸入框中輸入數(shù)據(jù),然后點(diǎn)擊“新增一個(gè)選項(xiàng)”,就能夠在底下的顯示區(qū)域動(dòng)態(tài)渲染每個(gè)選項(xiàng)。

如果我點(diǎn)擊了”編輯“按鈕,當(dāng)前元素就會(huì)被動(dòng)態(tài)渲染到輸入框中。如果我在輸入框進(jìn)行修改,底下的顯示區(qū)域也是實(shí)時(shí)動(dòng)態(tài)修改的。

如果我點(diǎn)擊了”刪除“按鈕,當(dāng)前元素就會(huì)從目標(biāo)對(duì)象中移除。

接下來(lái)看下代碼:

這是html代碼,父級(jí)中的兩個(gè)輸入框綁定的對(duì)象是newoption,這個(gè)對(duì)象就像是一個(gè)中介,如果需要push新對(duì)象到目標(biāo)數(shù)組,就先把值寫入newoption,然后把newoption的值push到目標(biāo)數(shù)組中去。如果需要修改目標(biāo)數(shù)組的元素,就把需要修改的元素的值傳給newoption,然后通過(guò)和newoption綁定的輸入框進(jìn)行數(shù)據(jù)渲染和修改。

其中#table的作用就是用一個(gè)v-for循環(huán)來(lái)動(dòng)態(tài)輸出目標(biāo)對(duì)象的每個(gè)元素,目標(biāo)對(duì)象就是list.options。并且每個(gè)元素都有”編輯“和”刪除“操作。

這是js代碼中的數(shù)據(jù)部分,其中options是我的目標(biāo)數(shù)組對(duì)象。而newoption是我的中介對(duì)象。

newoption對(duì)象會(huì)動(dòng)態(tài)存儲(chǔ)我在輸入框中輸入的數(shù)據(jù)。

這是在點(diǎn)擊”增加一個(gè)選項(xiàng)“的時(shí)候觸發(fā)的事件。

把newoption中的值push進(jìn)目標(biāo)數(shù)組。此時(shí)的this的指向是model實(shí)例。注意push的寫法。當(dāng)push成功后,選項(xiàng)列表是能夠馬上動(dòng)態(tài)渲染options的元素的(這個(gè)點(diǎn)我強(qiáng)調(diào)了好幾次,Vue的雙向綁定)。插入之后不需要對(duì)newoption進(jìn)行初始化。

這是在點(diǎn)擊”編輯“的時(shí)候觸發(fā)的事件。

把options對(duì)應(yīng)下標(biāo)的元素傳給newoption,用于進(jìn)行動(dòng)態(tài)修改。$index.指的就是循環(huán)中的”op“的下標(biāo)。此時(shí)的newoption和options[$index]都是指向同一個(gè)元素。

這是在點(diǎn)擊”刪除“的時(shí)候觸發(fā)的事件。

”op“指的是當(dāng)前在循環(huán)中渲染的元素,把當(dāng)前的元素對(duì)象$remove了,就完成了刪除的操作。

表單中的其他的數(shù)據(jù)渲染不存在數(shù)組的增刪查改,所以就不詳細(xì)說(shuō)明了。點(diǎn)擊網(wǎng)頁(yè)上的”提交“按鈕的操作只需要把data中的list對(duì)象通過(guò)ajax傳給后臺(tái)就好,并不需要自己構(gòu)造數(shù)組對(duì)象。

這樣才能算是實(shí)現(xiàn)了一個(gè)表單最基本的動(dòng)態(tài)綁定。

嗯。這就是在動(dòng)態(tài)組件上的思考過(guò)程。初次發(fā)文,謝謝大家。差不多了,我去吃個(gè)草莓。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容。關(guān)于...
    云之外閱讀 5,168評(píng)論 0 29
  • 所謂旅行,并非一定要去旅游景點(diǎn)。在我看來(lái),旅行是給自己的一次放逐。 用自己的眼,去觀察生活美好的部分,找到那種被景...
    時(shí)光隧道里的前行者閱讀 274評(píng)論 0 0
  • 不同類型文案的撰寫具有相通之處,這也是寫作的觸類旁通。廣告大師蘇立文在文案發(fā)燒書中,仔細(xì)闡述了廣告寫作的經(jīng)驗(yàn),而這...
    榴蓮柚閱讀 2,807評(píng)論 0 14
  • 27年的風(fēng)景,27年的經(jīng)歷,27年的成長(zhǎng),我只想對(duì)自己說(shuō),別把自己看的太重要,真的。世界上靠得住的信得過(guò)的只有自己...
    右岸偏右閱讀 258評(píng)論 0 0

友情鏈接更多精彩內(nèi)容