iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 29
0
Modern Web

For 前端小幼苗的圖解筆記系列 第 29

[Vue.js + Axios] ToDoList (下)

續前一篇的例子:

分段進行:


Vue 基本結構及使用到的屬性:

var app = new Vue({
    el: "#app",,
    data(){    // 定義資料 
        
    },
    created(){ // 初始完成 Vue 建立後要執行...
    
    },
    methods:{ // 定義在Vue或頁面中要使用的方法(function)
    
    },
    computed:{ // 進行計算的方法
    
    }
})

補充資料:


定義資料

  • 定義初始資料

    data() {
        return {
            todos: [],
            visibilityList: [  // 3種檢視清單(Tab)
                { name: "全部", value: "all" },
                { name: "進行中", value: "active" },
                { name: "已完成", value: "completed" }
                // name是頁面顯示文字,value是程式中操控的值 
            ],
            visibility: 'all',   // 當前檢視中的清單Tab,預設為全部
            cacheTodo: {},  // 暫存的Todo 
            cacheTitle: '' //暫存的項目名稱
        }
    }
    

讀取指定的 API 載入初始資料

  • 將 API 網址存成一變數

    var urlAPI = "https://eudora-hsj.github.io/Vue-practice/data/todolist.json"
    

    並且觀察一下 JSON 檔資料結構:

    {
        "data":
            [
                {
                    "id": "1",
                    "title": "買牛奶",
                    "completed": false
                },
                {
                    ...
                }
        ]
    }
    
  • 在 methods 裡定義讀取資料的 function(Axios)

    methods:{ 
        getList(url) {
            axios
                .get(url)
                .then((res) => {
                    this.todos = res.data.data
                })
                .catch((err) => {
                    console.log(err)
                })
        },
    }
    
  • 並且在 Vue 初始建立完成時執行 getList(url)

    this.getList(urlAPI)
    

可以新增(C)待辦項


  • 在對應的 DOM @dbclick / @keyup.enter 觸發事件
    <button class="btn btn-primary" type="button" @click="addTodo">新增</button>
    
    <input class="form-control" type="text" 
           v-model="newTodo" @keyup.enter="addTodo"/>
    
  • 定義的方法
    methods: {
        addTodo() {
            let newTodoStr = this.newTodo.trim()
            if (!newTodoStr) {
                return
            }
            this.newTodo = ""
            let submitData = {
                id: Math.floor(Date.now()),
                title: newTodoStr,
                completed: false
            }
            this.todos.push(submitData)
        }
    }
    

可以編輯(U)目前的待辦項


  • 在對應的 DOM @dbclick 觸發事件
    <li class="list-group-item" :key="item.id" @dblclick="editTodo(item)">
        (略)
    </li>
    
  • 定義的方法
    methods: {
        editTodo(item) {
            this.cacheTodo = item
            this.cacheTitle = item.title
        }
    }
    

可以刪除(D)待辦項

  • 在對應的 DOM @click 觸發事件
    <button class="close" type="button" @click="removeTodo(item)">
    </button>
    
  • 定義的方法
    刪除該項,並以 index 與 item 的 id 對應
    methods: {
        removeTodo(item) {
            this.todos.splice(this.getIndex(item.id), 1)
        }
    }
    

可以一次刪除所有待辦項

  • 在對應的 DOM @click 觸發事件
    <a href="#" @click="cleanTodo">清除所有任務</a>
    
  • 定義的方法
    filter 篩選出 completed 為 false 的資料並回傳筆數
    methods: {
        cleanTodo() {
            this.todos.splice(0, this.todos.length)
            }
        }
    }
    

補充資料:


頁籤(Tab)依完成狀態分類清單:全部 / 進行中 / 已完成

  • Tab 頁籤內容抓取自 data 裡的 visibilityList

  • @click,visibility 等於該 Tab 的 Value (all / active / completed )

  • 並且寫有當前Tab樣式的 active 要維持在 visibility 對應的 Tab

    <template v-for="(item, index) in visibilityList">
        <li class="nav-item" :key="index">
            <a class="nav-link" href="#" 
              :class="{'active' : visibility == item.value }"
              @click="visibility=item.value">
                  {{item.name}}
            </a>
      </li>
    </template>
    
  • 清單項目抓取自 filteredTodos 的結果(篩選出當前 Tab 的項目)

      <template v-for="(item) in filteredTodos">
        <li class="list-group-item">
         (略)
        </li>
      </template>
    
  • 計算的方法
    根據當前的 visibility 回傳對應狀態的項目

    computed: {
        filteredTodos() {
            let nowTab = this.visibility
            switch (nowTab) {
                case "all":
                    return this.todos.filter((item) => true)
                case "active":
                    return this.todos.filter((item) => !item.completed)
                case "completed":
                    return this.todos.filter((item) => item.completed)
            }
        },
    }
    

計數目前未完成的項,且有變動時即時更新計數

  • 在對應的 DOM 綁定顯示資料
    <div>{{`還有 ${activeTodosLength} 筆任務未完成`}}</div>
    
  • 計算的方法
    filter 篩選出 completed 為 false 的資料並回傳筆數
    computed: {
        activeTodosLength() {
            return this.todos.filter((item) =>            
                !item.completed).length
            }
        }
    }
    

參考資料:

個人 Blog: https://eudora.cc/


上一篇
[Vue.js + Axios] ToDoList (上)
下一篇
[線上工具] 分享 / [鐵人賽] 完賽心得
系列文
For 前端小幼苗的圖解筆記30

1 則留言

0
samshum
iT邦新手 5 級 ‧ 2021-02-05 10:49:55

寫得太好了,data是可以下載了.
可惜,更改,新增,或刪除好像只是改本地的資料?

---udate 2021-02-10
已經知道如何增刪改了,謝

我要留言

立即登入留言