2016-07-28 202 views
0

addTodo被觸發,我檢查其中的this,上下文是瀏覽器窗口,而不是data對象。因此todos最終未定義。爲什麼我的Vue方法沒有引用正確的上下文(數據)?

任何想法我失蹤?

HTML:

<div id="todo-list"> 
    <input type="text" v-model="newTodo"> 
    <button v-on:click="addTodo">Add</button> 
    <ul> 
    <li v-if="todos.length" v-for="todo in todos" class="todo-item"> 
     {{ todo }} 
    </li> 
    </ul> 
</div> 

JS:

new Vue({ 
    el: '#todo-list', 
    data: { 
    todos: [], 
    newTodo: '' 
    }, 
    methods: { 
    addTodo:() => { 
     this.todos.push(this.newTodo); 
     this.clearNewTodo(); 
    }, 
    clearNewTodo:() => { 
     this.newTodo = ''; 
    } 
    } 
}); 
+0

爲什麼使用addTodo:()=> {而不是addTodo:function(){} - 無論如何你的代碼是正確的,this.todos應該被定義。嘗試比較你的代碼和示例:https://vuejs.org/examples/svg.html – Xatenev

+0

@Xatenev我想我覺得它更短,更乾淨。這是ES6。但是,您提到的這一點提醒我,設置上下文(this)時,ES6箭頭函數與舊函數語法的行爲不同,並且將其更改爲舊語法可以修復問題。除非你這麼做,否則我會寫一個答案來解釋爲什麼這個工作在一秒鐘內完成。 –

+3

'()=>'將'this'的值更改爲封閉的上下文。在這種情況下,'this'可能等於'window'。這是你的問題。如果你想簡潔一些,你可以使用'addTodos(){}'而不是'addTodos:function(){}'。 –

回答

3

快速修復:don't use arrow functions to declare your Vue methods.

什麼問題?

你期待的ES6箭頭功能() => {}語法來設置上下文(this)一樣的舊函數聲明語法function() {}會。

這是爲什麼?

從MDN:

直到箭頭的功能,每一個新的功能定義了自己的這個值(在構造函數中,在嚴格模式下的函數調用不確定的情況下,一個新的對象,上下文對象,如果被調用的函數作爲「對象方法」等)。事實證明,這是一種面向對象的編程風格。

所以,你的方法對象應該是這樣的(使用舊的函數語法):

methods: { 
    addTodo: function() { 
     this.todos.push(this.newTodo); 
     this.clearNewTodo(); 
    }, 
    clearNewTodo: function() { 
     this.newTodo = ''; 
    } 

} 

或者這(使用new method definition syntax

methods: { 
    addTodo() { 
     this.todos.push(this.newTodo); 
     this.clearNewTodo(); 
    }, 
    clearNewTodo() { 
     this.newTodo = ''; 
    } 
    } 

我不知道大約是關於Vue.js如何設置/處理上下文的情況,但是看起來您的方法正在從您的模板/ DOM中調用,並且上下文將從那裏傳遞到您的方法中。由於箭頭函數繼承其上下文,因此this引用window對象。

使用實際函數聲明將保留對您想要的this的適當引用。

+1

您可以改爲使用'addTodo(){...}'。 –

+0

@BillCriswell你是對的 - 無論如何,這完全是es6。好決定。相應更新。 –

4

它看起來像ES6箭頭語法是你的問題。將其更改爲使用傳統的()函數的語法,它會工作:

addTodo: function() { 
 
    this.todos.push(this.newTodo); 
 
    this.clearNewTodo(); 
 
}, 
 
clearNewTodo: function() { 
 
    this.newTodo = ''; 
 
}

+0

啊太晚了!當我打字時,你已經明白了! :) – SteveB

+0

另外OP可以使用'addTodo()'而不是'addTodo:function(){'如果簡潔是他的顧慮。 –

0

你的箭頭Vue的方法已經得到this對象作爲第一個參數,所以:

methods: { 
    addTodo: (_this) => { 
     _this.todos.push(_this.newTodo); 
     _this.clearNewTodo(); 
    }, 
    clearNewTodo: (_this) => { 
     _this.newTodo = ''; 
    } 
    } 

的伎倆,但我不知道,箭頭的功能都在這裏貢獻什麼。

相關問題