Todos備忘錄項目詳解

今天咱們要作的是個備忘錄項目模仿一下Todos這是Todos的官方網址http://todomvc.com/examples/v...

操做流程

新建文件夾和文件名稱

自定義文件夾和文件名稱,咱們用它來裝咱們今天的項目css

打開命令行 依次輸入:

npm init -y // 初始化項目html

npm i -S underscore vue todomvc-app-css //下載這三個文件,由於咱們後期要用到vue

如圖這樣圖片描述node

在index.html裏邊輸入Vue的基本樣式和引入css、html:npm

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="./node_modules/todomvc-app-css/index.css">
</head>
<body>
        <section class="todoapp">
                <header class="header">
                    <h1>todos</h1>
                    <input class="new-todo" placeholder="What needs to be done?" autofocus="" >
                </header>
                <section class="main" v-show="showList">
                    <input class="toggle-all" id="toggle-all" type="checkbox">
                    <label for="toggle-all">Mark all as complete</label>
                    <ul class="todo-list">
                        <li>
                            <div class="view">
                                <input class="toggle" type="checkbox" >
                                <label></label>
                                <button class="destroy" ></button>
                            </div>
                            <input class="edit">
                        </li>
                    </ul>
                </section>
                <footer class="footer" v-show="showList">
                    <span class="todo-count">
                        <strong></strong></span>
                    <ul class="filters">
                        <li>
                            <a class="selected" href="#/">All</a>
                        </li>
                        <li>
                            <a href="#/active" >Active</a>
                        </li>
                        <li>
                            <a href="#/completed" >Completed</a>
                        </li>
                    </ul>
        
                    <button class="clear-completed" >Clear completed</button>
        
                </footer>
            </section>
    <script src="./../../vue.js"></script>
    <script>
        var app = new Vue({
            el:".todoapp",
             data:{
                
            }
        })
    </script>
</body>
</html>

在data中加入寫上一個數組,用來渲染到頁面,數組裏邊又是一個對象,由於咱們的一條數據裏會有不一樣的數據。

data:{
        todoList:[
            {
                text:"Vue很難",  //這個是任務的名稱
                checkbox:false  // checkbox的false表示未完成,true表示已完成
            },
            {
                text:"不難,只要用心", 
                checkbox:false
            }
        ]
    }

在li裏遍歷一下數據並綁定,在label中加入數據

<li v-for="(todo,index) in todoList">
    <div class="view">
        <input class="toggle" type="checkbox">
        <label>{{todo.text}}</label>
        <button class="destroy"></button>
    </div>
    <input class="edit">
</li>

給li元素動態綁定class,completed樣式的值,根據todo.checked, 若是todo.checked爲 true則有completed樣式。

<li v-for="(todo,index) in todoList"  :class="{completed: todo.checked}">

給checkbox加上v-model,值爲todo.checked, checked屬性會自動和todo.checked關聯

<input class="toggle" type="checkbox" v-model="todo.checked"/>數組

這樣咱們就能夠看到點擊複選框的效果了。mvc

在data中加入newTodo

data: {
    newTodo:"",
    todoList: [{
            text: "Vue很難", //這個是任務的名稱
            checked: false // checkbox的false表示未完成,true表示已完成 
        },
        {
            text: "不難,只要用心",
            checked: false
        }
    ]
}

刪除默認數據,由於咱們要用動態去添加,給咱們的輸入框動態綁定數據,並添加事件來提交內容。

<input class="new-todo" placeholder="你接下來須要完成什麼?" autofocus="" v-model="newTodo" @keyup.enter.trim="addTodo" />

緊接着咱們寫綁定事件的邏輯,新建模塊methods

methods: {
    addTodo() {
        this.newTodo = this.newTodo.trim(); //這句是去除空格 
        // 判斷輸入內容是否爲空,爲空不提交  
        if (this.newTodo.length < 1) {
            return;
        }
        //把新數據添加到數組當中,默認爲未完成
        this.todoList.unshift({
            text: this.newTodo,
            checked:false
        })
        this.newTodo = ""
    }
}

這樣咱們就能動態的添加數據了,而後咱們來作刪除數據功能

綁定刪除事件,由於咱們要用到underscore,因此引入

<button class="destroy" @click="deleteTodo(todo)"></button>

<script src="./node_modules/underscore/underscore-min.js" charset="utf-8"></script>

添加業務邏輯在methods中添加

deleteTodo(todo){app

this.todoList = _.without(this.todoList, todo)

}dom

咱們看到官網的頁面是沒有數據底部是消失的,因此咱們來完善一下

添加計算屬性

computed:{
        showList(){
            return this.todoList.length > 0
        }
    }

添加v-show

<footer class="footer" v-show="showList">

官網是雙擊數據是能夠進行編輯的

綁定數據

<input class="edit" type = "text" v-model = "todo.text">fetch

在data裏添加索引

editingIndex: -1

綁定雙擊事件

<label @dblclick="editTodo(index)">{{ todo.text }}</label>

在methods裏添加

editTodo(index) {

// 設置一下當前正在編輯的索引
this.editingIndex = index;

}

加上class

<li:class="{completed: todo.checked, editing: index === editingIndex}"
v-for="(todo,index) in todoList">

自定義一個屬性

// 註冊一個全局自定義指令 v-focus
Vue.directive('focus', {
// 當綁定元素插入到 DOM 中。
inserted(el) {

// 聚焦元素
el.focus()

},
// 當綁定元素更新的時候
update(el) {

el.focus();

}
})

添自定義屬性並綁定事件

<input class="edit" type="text" v-model="todo.text" v-focus="index === editingIndex" @blur="saveTodo(todo)" @keyup.enter="saveTodo(todo)"/>

寫事件

saveTodo(todo) {

this.editingIndex = -1
if (todo.text.trim().length < 1) {
  this.deleteTodo(todo)
}

}

未完成的個數

填寫邏輯在計算屬性中

activeCount() {

return this.todoList.filter(item => {
  return !item.checked
}).length;

}

渲染數據

<span class="todo-count">

<strong>{{activeCount}}</strong>

</span>

當刷新頁面咱們但願保留數據,這就須要咱們的存儲數據了

新建一個store.js並引入

在store.js中填寫
var STORAGE_KEY = 'todoList'
window.todoStorage = {

fetch() {
try {
  return JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]');
} catch(error) {
  return [];
}
},
save(todoList) {
    localStorage.setItem(STORAGE_KEY, JSON.stringify(todoList));
}

}

修改初始化數據

在data裏添加

todoList: todoStorage.fetch()

進行監聽,添加監聽模塊

watch: {
todoList: {

deep: true,
handler: todoStorage.save

}
}

所有完成功能的實現(選中和全選功能)

添加計算屬性

// 是否全部任務都完成
allDone: {

get() {
  // 未完成的數量爲0表示所有完成,所有完成返回true
  return this.activeCount === 0;
},
set(value) {
  this.todoList.forEach(todo => {
    todo.checked = value
  });
}

}

綁定數據

<input class="toggle-all" id="toggle-all" type="checkbox" v-model="allDone" />

頁面切換(all、active、Completed)

實例一個對象來實現過濾邏輯

var filters = {
all: function (todos) {

return todos;

},
active: function (todos) {

return todos.filter(function (todo) {
  return !todo.checked;
});

},
completed: function (todos) {

return todos.filter(function (todo) {
  return todo.checked;
});

}
};

在data裏添加一個屬性visibility 來表示咱們要顯示全部,仍是顯示未完成,或已完成

visibility: 'all'

修改一下未完成的數量這個計算屬性,使用上面的filters對象去過濾

computed: {
...
// 未完成的任務數量
activeCount() {

return filters.active(this.todoList).length;

},
}

添加任務過濾的計算屬性:

computed: {
...
// 過濾任務列表
filteredTodoList: function () {

return filters[this.visibility](this.todoList);

}
}

在DOM當中添加點擊事件,點擊的時候修改visiblity屬性便可

<li><a:class="{selected:visibility==='all'}"href="#/"@click="visibility='all'">all
</li>
<li>
<a
:class="{selected: visibility === 'active'}"
href="#/active"
@click="visibility = 'active'"

active
</li>
<li>
<a
:class="{selected: visibility === 'completed'}"
href="#/completed"
@click="visibility = 'completed'">completed
</li>
列表渲染的循環語句修改:

<li
:class="{completed: todo.checked, editing: index === editingIndex}"
v-for="(todo,index) in filteredTodoList" :key="'todo-'+index"

添加一個變量,獲得hash值:

var visibility = location.hash.substr(location.hash.indexOf('/')+1);
visibility = visibility === '' ? 'all' : visibility

設置visibility屬性的值爲當前的這個變量:

data: {
visibility: visibility,
...
}

點擊清空已完成功能:

添加一個已完成的任務數量計算屬性:

computed: {
...
// 已完成的任務數量
completedCount() {

return filters.completed(this.todoList).length;

}
}

添加一個清空已完成的方法:

methods: {
...
// 清空已完成的任務列表
clearCompleted() {

this.todoList = filters.active(this.todoList)

}
}

DOM元素綁定事件,以及v-show:

<button class="clear-completed" @click="clearCompleted" v-show="completedCount > 0">清空已完成</button>

相關文章
相關標籤/搜索