前提、質問
Vue.jsの学習をしています。
v-for
ディレクティブを用いて配列の要素をレンダリングしているのですが、
要素の値を変更する際に、直接要素の値を変更しても画面に反映されず、set()
を使う必要があることがわかりました。
このことについて二つ質問があります。
- 画面に反映されない理由は、配列が参照型だからVueが変化を検知せずに、レンダリングされないってことなんでしょうか?
違うとしたら、その理由が知りたいです。
- コンポーネントで同じように配列の要素の値を直接変更すると画面に反映されたのですが、何故でしょうか?
ソースコード
html
1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <title>Vue.jsテスト</title> 7 <style> 8 .delbtn { 9 margin-left: 10px; 10 } 11 12 .done { 13 color: gray; 14 text-decoration: line-through; 15 } 16 </style> 17</head> 18<body> 19 <div id="app"> 20 <h1>Todoリスト</h1> 21 <input type="text" v-model.trim="newtodo" placeholder="todoを入力してください" /> 22 <button @click="addTodo">追加</button> 23 <ul> 24 <li class="todolist" v-for="todo, index in todolist" v-bind:class="{done: todo.done}" @mouseover="todo.hover=true" @mouseout="todo.hover0=false"> 25 <input type="checkbox" v-model="todo.done" /> 26 <span>{{ todo.text }}</span> 27 <button class="delbtn" @click="remove(index)" v-show="todo.done && todo.hover">x</button> 28 </li> 29 </ul> 30 <ul> 31 <li v-for="(number,index) in colors" :key="index">{{ number}}</li> 32 </ul> 33 <button @click="colors[0] = 'white'">aaaa</button> 34 35 </div> 36 <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script> 37 <script src="./sample1.js"></script> 38</body> 39</html>
js
1var app = new Vue({ 2 el: '#app', 3 data: { 4 storageKey: 'todolist', 5 newtodo: '', 6 todolist: [], 7 colors: ["blue", "green", "red"] 8 }, 9 methods: { 10 addTodo: function () { 11 if (this.newtodo === '') { return; } 12 this.todolist.push({ text: this.newtodo, done: false, hover: false }); 13 this.newtodo = ''; 14 }, 15 remove: function (index) { 16 if (this.todolist[index].done === true) { 17 this.todolist.splice(index, 1); 18 } 19 }, 20 }, 21 created: function () { 22 var dataStr = localStorage.getItem(this.storageKey); 23 if (dataStr) { 24 this.todolist = JSON.parse(dataStr); 25 } 26 }, 27 watch: { 28 todolist: function () { 29 localStorage.setItem( 30 this.storageKey, 31 JSON.stringify(this.todolist) 32 ) 33 } 34 }, 35});
補足情報
この質問に関しては、ソースはいらないかと思いましたが、念のため貼り付けておきます。
ボタンをクリックした際に、配列colors
の要素を変更させて試してみた次第です。
あなたの回答
tips
プレビュー