[vue案例的知識點]todo-list


文章的原材料來自於vue的官方示例:https://cn.vuejs.org/v2/examples/todomvc.html,我們在學習過程中,試着對其中的一些知識點進行記錄:

一、瀏覽器數據存儲,為了方便,此處將數據存儲到客戶端的緩存中,使用localStorage,他的主要api有

  localStorage.getItem(key)和localStorage.setItem(key,value)

二、對於localStorage中的數據采取json數組形式保存,因此在保存value和獲取時候需要先做json和string的轉化,ECMA5提供了兩個轉化方法:

  將指定格式數據轉為json:JSON.parse(string);將json轉為string:JSON.stringify(json)

var TODO_KEY="vue-todo";

var todoStorage={
    fetch:function(){
        var todos=JSON.parse(localStorage.getItem(TODO_KEY)||'[]')
        todos.forEach(function(todo,index){
            todo.id=index;
        });
        todoStorage.uid=todos.length;
        return todos;
    },
    save:function(todos){
        localStorage.setItem(TODO_KEY,JSON.stringify(todos));
    }
}

三、使用hashchange監聽瀏覽器地址欄變化

  在單頁應用同頁跳轉的情況下,添加監聽window.addEventListener('hashchange',onHashChange)來獲取地址欄的變化,然后可以使用window.location.hash來監聽到地址欄的后綴變化,如果xxx.html#/all,此處值為"#/all",獲取地址欄的值變化,此處主要根據地址欄的visibility過濾不同的內容

function onHashChange(){
    var visibility=window.location.hash.replace(/#\/?/,'');
    if(filters[visibility]){
        app.visibility=visibility;
    }else{
        window.location.hash='';
        app.visibility='all';
    }
}
window.addEventListener('hashchange', onHashChange)
onHashChange()

三、json或者數組的過濾

  如果要根據todos中的completed的狀態過濾掉對應的子項,需要使用filter,如過濾掉非completed的項,是如下寫法

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

四、json或者數組中的某一項,修改

  如果要將todos的子項中的內容進行修改,需要使用forEach操作,如將所有completed修改為true,如下寫法:

            this.todos.forEach(function(todo){
                todo.completed=true;
            });

五、自定義vue標簽

        <input class="edit" type="text"
          v-model="todo.title"
          v-todo-focus="todo == editedTodo"
          @blur="doneEdit(todo)"
          @keyup.enter="doneEdit(todo)"
          @keyup.esc="cancelEdit(todo)">

在此input標簽中,我們希望如果是正在編輯的todo時候,自動被選中,此處自定義了一個v-todo-focus標簽,此標簽的格式如下

  directives: {
    'todo-focus': function (el, value) {
      if (value) {
        el.focus()
      }
    }
  }

指令定義,官方提供了五個鈎子函數來供我們使用,分別代表了一個組件的各個生命周期

bind: 只調用一次,指令第一次綁定到元素時調用,用這個鈎子函數可以定義一個在綁定時執行一次的初始化動作。

inserted: 被綁定元素插入父節點時調用(父節點存在即可調用,不必存在於 document 中)。

update: 被綁定元素所在的模板更新時調用,而不論綁定值是否變化。通過比較更新前后的綁定值,可以忽略不必要的模板更新(詳細的鈎子函數參數見下)。

componentUpdated: 被綁定元素所在模板完成一次更新周期時調用。

unbind: 只調用一次, 指令與元素解綁時調用。

在這里其他幾個都好理解,關於模板更新(update)這里,本人的理解是:該指令所在的模板有變化而需要重新渲染的時候,比如當一個輸入框的model發生了變化就會觸發指令。當然此處說的比較模糊,具體的還有待研究。

六、v-cloak標簽

vuejs做的界面加載過程中會閃現vue的變量,如{{msg}},在標簽加上v-cloak,在css定義可以解決此問題

[v-cloak] {
  display: none;
}

<section class="main" v-show="todos.length" v-cloak>

這段 CSS 的含義是,包含 v-cloak (cloak n. 披風,斗篷;vt. 遮蓋,掩蓋) 屬性的 html 標簽在頁面初始化時會被隱藏。

在 vuejs instance ready 之后,v-cloak 屬性會被自動去除,也就是對應的標簽會變為可見。問題來了,怎么才算是 ready 呢?這就需要了解 vuejs instance 的生命周期了

七、使用watch完成localStorage的寫入操作

  watch: {
    todos: {
      handler: function (todos) {
        todoStorage.save(todos)
      },
      deep: true
    }
  },

在todo-list的應用中,整個操作過程中的增刪改查操作很多,系統使用todos來保存每次操作后的結果,然后使用watch監控todos的變化,完成緩存的更新,注:deep表示深復制,即元素發生變化,也會導致他的變化

八、計算屬性和觀察屬性

在todo-list有一個全選按鈕,如果選中的時候,所有任務被標記為完成,如果任務全部完成,此標記也會被標記選中

1、以下是我的實現,對allDon進行watch,如果發生了改變,則修改所有任務狀態,

        allDone:function(){
            this.allDone!=this.allDone;
            var selDone=this.allDone;
            this.todos.forEach(function(todo){
                todo.completed=selDone;
            });
        }

同時在computed計算remaining的時候,根據remaining修改allDone

        remaining:function(){
            var remaining=filters.active(this.todos).length;
            this.allDone=remaining===0?true:false;
            return remaining;
        }

2、以下是官方實現,使用computed的get和set操作allDone,減少了元素定義,也更為清晰

    allDone: {
      get: function () {
        return this.remaining === 0
      },
      set: function (value) {
        this.todos.forEach(function (todo) {
          todo.completed = value
        });
      }

九、數組的操作-使用push和slice進行添加數組元素和刪除數組元素,略

十、使用filters進行格式化,此處其實可以使用computed進行實現

filters: {
    pluralize: function (n) {
      return n === 1 ? 'item' : 'items'
    }
  },

十一、在做var app=new Vue()的時候,我們可以不用指定元素,等其他初始化完成后,最后一步再使用mount進行綁定

// mount
app.$mount('.todoapp')

 十二、對於todo的編輯和展示切換

對於某一條todo,我們要求雙擊進行切換到編輯模式,回車切換到展示模式,我們的處理是:對於此todo,兩種模式在頁面上共存,通過method方法,改變對應的class,達到切換的目的。

      <li v-for="todo in filteredTodos"
        class="todo"
        :key="todo.id"
        :class="{ completed: todo.completed, editing: todo == editedTodo }">
        <div class="view">
          <input class="toggle" type="checkbox" v-model="todo.completed">
          <label @dblclick="editTodo(todo)">{{ todo.title }}</label>
          <button class="destroy" @click="removeTodo(todo)"></button>
        </div>
        <input class="edit" type="text"
          v-model="todo.title"
          v-todo-focus="todo == editedTodo"
          @blur="doneEdit(todo)"
          @keyup.enter="doneEdit(todo)"
          @keyup.esc="cancelEdit(todo)">
      </li>

代碼可以看到,顯示todo的地方有一個div用於顯示,一個input用於編輯,根據editedTodo來確定是否給li綁定editing的class,如果綁定后,class如下,顯示edit,隱藏view

.todo-list li.editing .edit {
    display: block;
    width: 506px;
    padding: 12px 16px;
    margin: 0 0 0 43px;
}

.todo-list li.editing .view {
    display: none;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM