這次用vue實(shí)現(xiàn)簡(jiǎn)單的做事列表單许师。包含事件添加房蝉、統(tǒng)計(jì)、刪除微渠、標(biāo)記(已完成/未完成)搭幻。
一、功能實(shí)現(xiàn)
做事列表也是通過(guò)v-for循環(huán)渲染出的列表效果逞盆,根據(jù)data中plans數(shù)據(jù)獲取到的檀蹋,也可以通過(guò)axios獲取json數(shù)據(jù)。
(1)事情獲取和狀態(tài)分類
首先先介紹如何將所有數(shù)據(jù)分成:全部任務(wù)云芦、已完成俯逾、未完成。這里剛開(kāi)始定義當(dāng)isSekected為true時(shí)就是完成狀態(tài)舅逸。這些分類后的數(shù)據(jù)列表是通過(guò)計(jì)算的到的桌肴,所以采用computed計(jì)算屬性來(lái)實(shí)現(xiàn)。
再者就是琉历,怎么通過(guò)點(diǎn)擊不同的鏈接顯示不同狀態(tài)的數(shù)據(jù)坠七?這里使用hash值來(lái)區(qū)分水醋。即通過(guò)在網(wǎng)址后面加哈希值來(lái)顯示不同條件的結(jié)果。然后再computed中我們根據(jù)不同鏈接的hash值彪置,來(lái)計(jì)算不同的狀態(tài)數(shù)據(jù)拄踪。
在vue實(shí)例中,定義computed中的屬性filterPlans拳魁,實(shí)現(xiàn)根據(jù)不同的hash值返回不同的顯示數(shù)據(jù)惶桐。(finish表示被選中的,unfinish表示沒(méi)有選中的)(只要理清邏輯潘懊,實(shí)現(xiàn)很簡(jiǎn)單^.^)
然后在v-for中遍歷的數(shù)據(jù)改成filterPlans即可姚糊。
(2)未完成統(tǒng)計(jì)
跟上面的原理差不多,也是根據(jù)computed計(jì)算屬性計(jì)算得到count的值卦尊,通過(guò){{}}渲染在頁(yè)面上叛拷。
這里要記住一個(gè)原則:只要是要顯示計(jì)算屬性的值舌厨,就寫在computed里面岂却。
漏了一點(diǎn):前面講到通過(guò)hash值顯示不同的狀態(tài)數(shù)據(jù),實(shí)現(xiàn)動(dòng)態(tài)刷新的效果裙椭。但是在頁(yè)面初始化加載躏哩,即created函數(shù)中,需要監(jiān)控hash的變化揉燃,即如果頁(yè)面已經(jīng)有hash值了扫尺,重新刷新頁(yè)面也要獲取hash值。并且將hash值的變化映射到數(shù)據(jù)內(nèi)炊汤。(hash值只需要后面的名字正驻,不用‘/#’這兩個(gè)字符)
只有這樣才能將窗口里面的hash值成功傳到this.hash中,才能真正顯示不同的狀態(tài)數(shù)據(jù)抢腐,否則點(diǎn)擊那幾個(gè)標(biāo)簽是沒(méi)有任何反應(yīng)的姑曙。下面代碼添加到created()中:
this.hash = window.location.hash.slice(2) ||"all"; // 如果沒(méi)有觸發(fā),也需要初始化一個(gè)hash值
window.addEventListener('hashchange',()=>{
this.hash = window.location.hash.slice(2);
},false)// 這里默認(rèn)就是false
(3)添加和刪除
這個(gè)很簡(jiǎn)單迈倍,就創(chuàng)建兩個(gè)methods:remove和add伤靠,分別使用filter和push數(shù)組方法改變數(shù)組的元素。
二啼染、完善
(1)為了讓做事列表的狀態(tài)有區(qū)分宴合,更美觀,需要到選擇該條事情標(biāo)記為已完成時(shí)改變它的顯示效果迹鹅。如:
這里使用class動(dòng)態(tài)綁定實(shí)現(xiàn)卦洽,即當(dāng)isSelected為true時(shí)添加相應(yīng)的class
:class="{del:one.isSelected}",one是指循環(huán)中的某一條數(shù)據(jù)斜棚,del是自定義的css樣式逐样。
關(guān)于class和style的用法,更詳細(xì)的可以參照vue官方教程-class&style
(2)允許修改添加后的事件
即雙擊該行進(jìn)入可編輯狀態(tài),失去焦點(diǎn)或回車回到原來(lái)的模式并顯示修改后的結(jié)果脂新。
這種情況挪捕,由于當(dāng)前雙擊的一條li和其他有區(qū)分,可以事先寫兩個(gè)input争便,使用v-show级零,根據(jù)不同的條件顯示不同的input,當(dāng)雙擊的某項(xiàng)時(shí)滞乙,將該項(xiàng)one傳給當(dāng)前項(xiàng)cur娱挨,如果one==cur,則根據(jù)自定義的指令v-focus航缀,實(shí)現(xiàn)讓輸入框獲取焦點(diǎn)芳誓。如果li失去焦點(diǎn)或者回車,則執(zhí)行cancel將cur=''兔簇,這樣滿足one发绢!=cur,顯示上面的input垄琐。
自定義指令需要定義在directtives里面:
editor和cancel方法實(shí)現(xiàn):
(3)還需要一個(gè)功能:當(dāng)數(shù)據(jù)發(fā)生變化時(shí)實(shí)時(shí)將數(shù)據(jù)傳到本地存儲(chǔ)localStorage边酒,這樣關(guān)掉之后再打開(kāi)仍會(huì)顯示之前的結(jié)果。
①頁(yè)面初加載時(shí)狸窘,如果本地localStorage有數(shù)據(jù)用他里面存的墩朦,如果沒(méi)有則用默認(rèn)的。
this.plans = JSON.parse(localStorage.getItem('data')) ||this.plans;
②有了獲取翻擒,當(dāng)然要時(shí)刻監(jiān)控?cái)?shù)據(jù)變化并且存到本地存儲(chǔ)中setItem氓涣。
watch只能監(jiān)控一層的數(shù)據(jù)變化,即數(shù)據(jù)plans中如果數(shù)組添加一個(gè)對(duì)象陋气,則能監(jiān)控到劳吠,但是若只是改變數(shù)組中某個(gè)對(duì)象的val則不會(huì)被監(jiān)控到,比如對(duì)某條進(jìn)行修改恩伺。如果是要進(jìn)行深度監(jiān)控赴背,我們需要把plans變成一個(gè)對(duì)象。
localStorage默認(rèn)存的是字符串晶渠,getItem--用JSON.parse和setItem--用JSON.stringify進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換
watch:{
? ? plans:{
handler(){
? ? ? ? ? ?localStorage.setItem('data',JSON.stringify(this.plans));
? ? ? ? },deep:true
? ? }
},
描述不準(zhǔn)確或者錯(cuò)誤的地方請(qǐng)多多指教;思浴!褒脯!
完整代碼參考參考vue-demo中的newTodo.html和newTodo.js