Vue 初心者筆記 #8 TodoList 新增功能

學習 Vue.js 元件的基礎用法後,我們來試著做出一個 Todo List 看看!本篇筆記介紹如何做出「新增」待辦事項的功能。

「新增」待辦事項的功能

步驟如下:

  1. 新增新的代辦事項內容
  2. 可透過鍵盤新增代辦事項
  3. 可透過按鈕將代辦事項加到 todos 裡面
  4. Todo 列表
  5. 預設資料
  6. 定義資料
  7. 將 input id 與 label for 做 v-bind 綁定
  8. 綁定 item.completed
  9. Debug:修正程式讓使用者無法新增空白的待辦事項

STEP 1:新增新的代辦事項內容

使用 v-model 綁定 input 與資料

1
<input type="text" class="form-control" placeholder="準備要做的任務" v-model="newTodo">

STEP 2:透過鍵盤新增代辦事項

使用 @keyup.enter 綁定 input 與 Enter 行為

1
<input type="text" class="form-control" placeholder="準備要做的任務" v-model="newTodo" @keyup.enter="addTodo">

功能同第 3 點

STEP 3:透過按鈕把代辦事項加到 todos 裡面

使用 v-on:click 綁定 input 與 click 行為

1
<button class="btn btn-primary" type="button" @click="addTodo">新增</button>

功能同第 2 點

STEP 4:Todo 列表

使用到 v-for 獲取陣列的每個資料

1
<li class="list-group-item" v-for="item in todos">

STEP 5:預設資料

data 新增 newTodo 與 todos
methods 新增 addTodo

1
2
3
4
5
6
7
8
9
10
11
12
<script>
var app = new Vue({
el: '#app',
data: {
newTodo: '', // v-model
todos: [], // v-for
},
methods: {
addTodo: function(){}, // v-on
},
});
</script>

newTodo 預設為空字串
todos 預設為空陣列

STEP 6:定義資料

  • newTodo 是輸入代辦事項的地方,因此預設要是一個空字串

  • todos 是代辦事項的屬性,有 id、title、completed 三種

  • addTodo 是 methods 裡的一個 function

    1. 宣告 value 與 timestamp

      1
      2
      let value = this.newTodo;
      let timestamp = Date.now();
    2. timestamp 取得毫秒數後 轉成正整數

      Date.now() 方法回傳自 1970/01/01 00:00:00 UTC 起經過的毫秒數
      轉成正整數:Math.floor()

      1
      let timestamp = Math.floor(Date.now());
    3. 以物件格式 push 到 todos 陣列裡面

      push 物件到陣列裡面

      1
      2
      3
      4
      5
      this.todos.push({
      id: timestamp,
      title: value,
      completed: false,
      });
    4. 最後清空輸入字串 (newTodo)

      輸入後自動清空 input 欄位

      1
      this.newTodo = '';

範例程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<script>
var app = new Vue({
el: '#app',
data: {
newTodo: '',
todos: [
{
id: '345',
title: '妳好',
completed: false,
}
],
},
methods: {
addTodo: function(){
let value = this.newTodo;
let timestamp = Math.floor(Date.now());
console.log(value, timestamp);

this.todos.push({
id: timestamp,
title: value,
completed: false,
})

this.newTodo = '';
}
},
});
</script>

STEP 7:將 input id 與 label for 做 v-bind 綁定

表單中的 input id 對應 label for 是固定的用法

這裡一定要用 v-bind 來綁定
才能將不同資料的 id 綁定上去

1
2
3
4
<input type="checkbox" class="form-check-input" :id="item.id">
<label class="form-check-label" :for="item.id">
{{ item.title }}
</label>

STEP 8:綁定 item.completed

使用 v-model 綁定 input 與 data 裡的 completed

1
2
3
4
5
6
7
<input type="checkbox" class="form-check-input"
:id="item.id"
v-model="item.completed">

<label class="form-check-label" :for="item.id">
{{ item.title }}
</label>

Bug 修正

  • 修正「沒有輸入內容也能新增」的 Bug
    做法:在 addTodo 新增條件,如果 value 沒有值,就直接 return(結束函式)
    if(!value){ return; }

    ! 是否定的意思
    所以當 value 值不存在時(或為否定)
    就會執行該段程式碼

  • 修正待辦事項「輸入空白就能新增」的 Bug
    做法:在 value 加上 String.trim() 方法,可將「字串前後的多餘空白」去除
    let value = this.newTodo.trim();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
methods: {
addTodo: function(){
// 去除字串前後的空白
let value = this.newTodo.trim();
let timestamp = Math.floor(Date.now());
// 檢查 value 是否為空值
if(!value){
return;
}
console.log(value, timestamp);
this.todos.push({
id: timestamp,
title: value,
completed: false,
})
this.newTodo = '';
}
},

結語

經過以上 8 個步驟與小 Bug 的修正
我們就可以順利使用按鈕與按鍵來「新增」待辦事項囉!

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫。