2016-07-28 6 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です。しかし、ES6の矢印関数は、コンテキスト(this)を設定するときに古い関数構文と同じ振る舞いをしていないことを覚えています。古い構文に変更すると問題が解決されます。私はあなたがしなければ、なぜこれが秒で動作するのかの答えを書くつもりです。 –

+3

'()=>'は 'this 'の値を囲むコンテキストに変更します。この場合、「this」は「window」と等しくてもよい。あなたの問題があります。簡潔にするには 'addTodos:function(){}'の代わりに 'addTodos(){}'を使うことができます。 –

答えて

3

クイックフィックス:don't use arrow functions to declare your Vue methods.

問題は何ですか?

() => {}の構文では、コンテキスト(this)を旧関数の宣言構文function() {}と同じに設定すると期待しています。

なぜそれが問題ですか? MDNから

:矢印機能まで

関数が呼び出された場合、すべての新しい機能がstrictモード関数呼び出しに未定義独自のこの値(コンストラクタの場合は、新しいオブジェクト、コンテキストオブジェクトを定義し「オブジェクトメソッド」など)。これは、オブジェクト指向のプログラミングスタイルに迷惑をかけることが判明しました。

だから、あなたのメソッドオブジェクトが(古い関数の構文を使用して)次のようになります。

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からメソッドが呼び出されており、コンテキストがそこからメソッドに渡されているようです。矢印関数はコンテキストを継承するため、thiswindowオブジェクトを参照します。

実際の関数宣言を使用すると、希望する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:function(){'の代わりに 'addTodo()'を使うことができます。 –

0

あなたの矢印Vueの方法はまだ、最初のパラメータとしてthisオブジェクトを取得している:

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

は、トリックを行いますが、私は矢印の機能がここで何を貢献していることを確認していません。

関連する問題