刪除線效果

STEP 1:新增 CSS 樣式

在 .completed 新增刪除線樣式

.completed {
  text-decoration: line-through;
}

STEP 2:v-model 綁定資料

單選的 Checkbox 用 v-model 綁定後
原本的 false 打勾後會變成 true

<input
  type="checkbox"
  class="form-check-input"
  :id="item.id"
  v-model="item.completed"
/>

STEP 3:動態切換 className

打勾後 item.completed 的變動 = 動態加入 className

前面 className 建議用字串格式來寫

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

頁籤切換效果

STEP 1:新增變數 visibility

新增一個變數叫做 visibility
表示目前呈現哪一個頁籤
這邊先填入 all 代表預設顯示的頁籤是全部內容的頁籤

var app = new Vue({
  el: '#app',
  data: {
    newTodo: '',
    todos:
    // 新增變數
    visibility: 'all',
  },
  methods: {...},
});

STEP 2:使用 :class 判斷式新增 active

BS4 的 nav-link 如果有 active 這個 class
畫面上就會呈現外框,表示目前的 Tab 是哪一個

先把它刪除,我們自己新增 :class

前面是變數名稱 'active'
後面是判斷式 visibility == 'all'

變數 visibility 的值如果是 all,"全部"這個頁籤就會啟動 active 的狀態

<a class="nav-link" href="#" :class="{'active': visibility == 'all'}">
  全部
</a>

複製此效果到其他兩個頁籤
值改成 active(進行中) 與 completed(已完成)
:class="{'active': visibility == 'active'}"
:class="{'active': visibility == 'completed'}"

STEP 3:加上切換條件

接著加上切換條件 @click="visibility = 'all'"

注意這邊的 visibility = 'all' 只有一個等號

同樣將效果套用到其他兩個頁籤上
值改成 active(進行中) 與 completed(已完成)

補充:在 @click 加上 .prevent,可解決點擊後畫面跑到最上方的問題

頁籤範例程式碼

<li class="nav-item">
  <a
    class="nav-link"
    href="#"
    :class="{'active': visibility == 'all'}"
    @click.prevent="visibility = 'all'"
  >
    全部
  </a>
</li>
<li class="nav-item">
  <a
    class="nav-link"
    href="#"
    :class="{'active': visibility == 'active'}"
    @click.prevent="visibility = 'active'"
  >
    進行中
  </a>
</li>
<li class="nav-item">
  <a
    class="nav-link"
    href="#"
    :class="{'active': visibility == 'completed'}"
    @click.prevent="visibility = 'completed'"
  >
    已完成
  </a>
</li>

因此,點擊"已完成"頁籤時,visibility 的值會等於 completed
同時也觸發了「加上 active 這個 className」的條件 (visibility == 'completed')

這邊就完成切換頁籤的功能了

資料過濾

完成頁籤切換後,資料還沒有辦法切換
因為資料還沒有做「過濾」

STEP 1:宣告 filteredTodos 方法

目前呈現資料是用 todos (原始資料)
而我們要呈現的應該是過濾後的資料

因此我們在 methods 下面再新增一個 computed
並宣告一個方法 filteredTodos

computed: {
    filteredTodos: function(){
        return this.todos;
  },

並把 filteredTodos 替換上來

<li class="list-group-item" v-for="(item, key) in filteredTodos">
  ...
</li>

完成後,我們之後運用的資料就是 filteredTodos 的資料
也就是經過「過濾後」的資料

STEP 2:過濾資料 - 「全部」頁籤

呈現 visibility 為 'all' 的物件

當 visibility == 'all' 的時候,回傳 todos
否則回傳空陣列

computed: {
  filteredTodos: function(){
    if(this.visibility == 'all'){
      return this.todos;
    }else{
      return [];
    }
  }
},

完成這個步驟後,"進行中" 與 "已完成" 就沒有資料了

因為 visibility 不是 'all' 的 filteredTodos 物件
都變成一個一個空陣列的物件了

STEP 3:過濾資料 - 「進行中」頁籤

呈現 visibility 為 'active' 的物件

在 visibility == 'active' 的情況下
先宣告一個空陣列 newTodos
let newTodos = [];
預計用來接收 todos 裡面沒有完成的資料內容

接著從 todos 裡面找出未完成的資料(使用 forEach
假設這個 item 的 completed 是 "未完成" 的
就把這個 item 新增到 newTodos 裡面(使用 push()

最後 return newTodos 呈現結果

computed: {
    filteredTodos: function(){
      if(this.visibility == 'all'){
        return this.todos;
      }else if(this.visibility == 'active'){
        let newTodos = [];
        this.todos.forEach(function(item){
          if(!item.completed){
            newTodos.push(item);
          }
        });
        return newTodos;
      }
    }
  },

STEP 4:過濾資料 - 「已完成」頁籤

呈現 visibility 為 'completed' 的物件

假設 visibility 是 completed 的情況下
else if(this.visibility == 'completed'){}

如果這個 Todo 是 "已完成" 的話,就把資料加進來
if(item.completed){ newTodos.push(item); }

最後回傳結果
return newTodos;

範例程式碼

computed: {
    filteredTodos: function(){
        // 全部
        if(this.visibility == 'all'){
            return this.todos;

        // 進行中
        }else if(this.visibility == 'active'){
            let newTodos = [];
            this.todos.forEach(function(item){
                if(!item.completed){
                    newTodos.push(item);
                }
            });
        return newTodos;

        // 已完成
        }else if(this.visibility == 'completed'){
            let newTodos = [];
            this.todos.forEach(function(item){
                if(item.completed){
                    newTodos.push(item);
                }
            });
        return newTodos;
        }
    }
},

結語

這樣子頁籤切換功能就完成囉!
下一篇會介紹如何修改已新增的待辦事項內容

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