or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
![image alt](https:// "title") | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | Emoji list | ||
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing
xxxxxxxxxx
【Vue電商】Todo List 練習
tags:
vue
任務:todo list
Udemy:https://www.udemy.com/course/vue-hexschool/learn/lecture/10271404#overview
基本功能:
會顯示全部代辦事項;
點擊「進行中」:
會顯示未完成代辦事項;
點擊「已完成」:
會顯示完成代辦事項;
進階功能:
按下新增button(或enter時)時會新增代辦事項
在最上方的輸入欄,即是
<input>
使用v-model
,此v-model
是連接vue的data裏的newTodo
,讓我們能夠在newTodo
儲存使用者所輸入的代辦事項。在「新增」button設定
@click="addTodo"
,以及在<input>
欄位設定@keyup.enter="addTodo"
。作用是當使用者按下新增或enter鍵時,就執行addTodo
函式。Vue:
addTodo
函式的作用是用.push
方法,把新增的代辦事項加進todos
裏。每筆代辦事項都需要有:因此,
addTodo
的函式應該是這樣:為什麼需要
id
?因為每個代辦事項左邊都有個checkbox,該代辦事項的id需要與該checkbox的id相同,才可以使我們點擊該代辦事項的title時,就可以對應點擊到該checkbox。因此,每個代辦事項都要有一個獨有的id。
用
Date.now()
方法產生idDate.now()
會產生一組數字,該數字是自 1970/01/01 00:00:00 UTC 起經過的毫秒數。之後用Math.floor()
(取小於這個數的最大整數)去取整數。顯示代辦事項
在checkbox使用
v-model
在checkbox使用
v-model
,會得出boolean值。因此可以操控該代辦事項的complated狀態是true
還是false
。詳情:https://vuejs.org/v2/guide/forms.html
v-bind
和v-on
縮寫v-bind
縮寫:用
:
。例如::class=""
、:id=""
v-on
縮寫:用
@
。例如:@click=""
、@dblclick=""
、@keyup.enter=""
防止輸入空白值(自己做的時候漏掉這部分)
為了防止使用者新增空白的代辦事項,我們需要在
addTodo
函式裏做判斷。以下修改一下addTodo
函式:按下「x」後會刪除資料
先寫以下做法:
這個做法是把該事項的index直接傳進函式裏,並用它來刪掉資料。
為什麼會有bug?因為當我們轉到其他頁籤時,該頁籤的陣列資料(filterTodo)會不同於原始陣列(todos)。
例如以下情況,我新增了1,2,3,4,完成了2,3,之後我按下已完成頁籤,想刪除3,你會發現3並沒有被刪掉,反而是2被刪除:
這是因為在filterTodo陣列裏,第2筆資料是「3」,但是在todos這個原始陣列裏,第2筆資料是「2」,所以反而是「2」被刪掉了。
因此,要改用以下的寫法:
這個方法就是把該代辦事項的id傳進來
deleteTodo
,然後在deleteTodo
裏,利用傳進來的id,找尋此id在原始陣列todos裏的index(我命名為todoIndex),最後利用todoIndex在todos陣列裏刪除該筆代辦事項。這個做法就成功解決那個bug了。
把已完成的代辦項目加上劃線的class
當使用者完成該代辦事項時,該項目會有劃線效果:
CSS樣式:
當該代辦事項的completed狀態是true時,就會加上
completed
CSS樣式。頁籤分類效果(自己做時這裏有卡關)
以上這些功能,可以大概猜出這裏需要一個過濾功能,例如:
但我們不需要每個狀態都開一個新陣列,例如開一個叫
activeTodos
、completedTodos
,把完成和未完成的項目從todos裏面抽取來,並分別push進這兩個陣列裏,這是很累贅的做法。我們可以這樣想:
這是原本放置所有代辦事項的陣列,我們不要動這個陣列。
這是一個會變動的陣列。它要做的事就是,看你點擊到哪個頁籤,它就按哪個頁籤去過濾todos陣列,並回傳過濾好的資料。
如何看你點擊哪個頁籤?我們可以在
data
裏設定一個變數,該變數會顯示目前使用者在哪個頁籤,我們把該變數取命為visibility
:在HTML的部分,設定當該頁籤被點擊時,就會更改
visibility
的變數值:另外,在頁籤的部分,當該頁籤被點擊後,就會被加上
active
這個CSS樣式,例如我點擊了「進行中」後,「進行中」被框起來,以及文字變灰色:所以以上程式碼中,也用
:class
綁定active
這個CSS樣式。回到Vue的部分,這時候我們會用到
computed
,重溫computed
特性:methods
是沒有緩存機制,不管資料有沒有更新,它都會重新渲染。在我們的情況,因為當todos陣列(即是放置所有代辦項目的那個陣列)裏有項目被checked,即是被標記為完成,理論上,「進行中」和「已完成」頁面就需要被更新,「進行中」會顯示少了一個項目,「已完成」會顯示多了一個項目。
反之,todos陣列裏沒有變動,就不用重新渲染畫面。
所以這裏用
computed
。之後我們要改成在
filterTodo
裏撈資料,而非原始陣列todos
:雙擊編輯代辦事項(自己做時這裏有卡關)
接下來要做的功能就是當使用者雙擊該代辦事項時,就會切換成輸入欄位,讓使用者修改該代辦事項的title,如下圖:
這個效果有幾個功能要做:
修改該代辦事項的title
利用
@dblclick=""
來設定雙擊事件,並且執行editTodo
函式。html的部分:
Vue的部分,我們將該正在被修改的那筆代辦事項以及它的title暫存起來:
以下會再解釋為什麼要暫存該筆代辦事項的資料。
隱藏原本的代辦事項,並打開input輸入欄
雙擊後,就要隱藏原本的代辦事項,並打開input輸入欄。我們可用
v-if
去寫出這個效果:以上程式碼解釋了為什麼剛剛我們需要暫存該筆事項,因為在這裏的隱藏/顯示功能中,需要用該筆事項去做判斷:
如果這個代辦事項的id 與 暫存中的代辦事項id相同,就代表這個代辦事項正在被編輯,所以要隱藏原本的資料欄,並打開輸入欄位。同一道理,如果該代辦事項的id 不等於 暫存的id,那就意味該筆代辦事項並沒有正在被修改,所以就隱藏輸份欄,只顯示資料欄。
這裏用
v-if
去寫出效果,v-if
的用法就是只要條件是true,就會渲染該元素。v-if
VSv-show
題外話:
v-if
:條件是true才會渲染v-show
:不管條件是否true都會渲染,並用CSSdisplay
屬性去隱藏或顯示。所以:
v-show
v-if
詳細看:https://vuejs.org/v2/guide/conditional.html
雙擊修改時,預設會先顯示原本的title
重看上面那張gif,可見雙擊代辦事項,並切換到輸入欄後,輸入欄會預設顯示該代辦項目原本的title(這個gif例子中就是「1」),而非空白:
所以,我們需要在輸入欄位,預設會顯示該筆事項的title。這裏使用
v-model
去把title顯示出來:按esc後取消編輯,按enter儲存編輯
Vue部分:
以上做法就是清空暫存的代辦事項,作用就是退出編輯。
顯示還剩下多少未完成項目
刪除所有資料
完整程式碼
https://codepen.io/alysachan/pen/bGevJBV