HTML5テクニカルノート
Vue.js + ES6入門 06: 項目を調べてデータから削除する
- ID: FN1906003
- Technique: HTML5 / ECMAScript 2015
- Library: Vue.js 2.6.10
データバインディングは、データにもとづいてページの表示を動的に描き替える仕組みです。今回は、ページのリスト項目を削除します。考えるのは、ユーザーの操作や条件に応じて、項目のデータをどうやって選んで除くかです。
01 ボタンを加える
「Vue.js + ES6入門 05: 項目を数えて表示する」でつくったコード002「Array.prototype.reduce()メソッドで配列を集計する」に手を加えてゆきましょう。アプリケーションに納めた複数のデータがリストとして示され、入力フィールドのテキストは「追加」ボタンで項目に加えられます。また、項目すべてとチェックのついていない数も、それぞれ示されています(図001)。
図001■全項目数と残りの数が示される
チェック済みの項目だけを、まとめて除けるようにしましょう。クリックする<button>
要素を、つぎのように加えます(図002)。v-on:click
(省略記法@click
)ディレクティブから呼び出すメソッド(archive
)はつぎの項で定めます。
<body>要素<div id="app" class="container"> <p> 全{{todos.length}}件中残り{{remaining}}件 <button @click="archive" class="btn btn-danger btn-sm">断捨離</button> </p> </div>
図002■件数の右にボタンが加わった
02 条件にしたがってデータを除く
ボタンから呼び出されるのは、methods
オプションに加えたつぎのメソッド(archive()
)です。チェックをつけた項目は、データのプロパティ(done
)の値がtrue
になります。そこで、データ(todo
)の中からチェックのついていない項目だけを取り出した新たな配列で、もとのリスト項目データ(todos
)に上書きしました。Array.prototype.filter()
メソッドを使ったこの処理は、「Vue.js + ES6入門 05」のコード001「条件に合ったデータを数えて返す」のremaining
算出プロパティと同じです。このときは、使うのは配列でなく項目数だったため、あとでArray.prototype.reduce()
メソッドで書き直したのでした(同コード002)。けれど、今回はまさに配列がほしい場合です。
<script>要素const app = new Vue({ data: { todos: [ {text: 'Vue.jsを学ぶ', done: true}, {text: 'Vue.jsでアプリケーションをつくる', done: false}, ] }, methods: { archive() { this.todos = this.todos.filter((todo) => !todo.done); } }, });
これで、ボタンを押すとチェック済みの項目はデータから除かれ、画面にはチェックされていない項目だけが残ります(図003)。ここまでのHTMLとJavaScriptの記述は、以下のコード001にまとめました。
図003■チェック済みの項目が除かれた
コード001■条件にしたがってデータから項目を除く
<body>要素
<div id="app" class="container">
<h2>Todo</h2>
<p>
全{{todos.length}}件中残り{{remaining}}件
<button @click="archive" class="btn btn-danger btn-sm">断捨離</button>
</p>
<ul class="list-unstyled">
<li v-for="todo in todos">
<label>
<input type="checkbox" v-model="todo.done">
<span :class="{'done': todo.done}">{{todo.text}}</span>
</label>
</li>
</ul>
<p>
<input type="text" v-model="todoText" placeholder="add new todo here">
<button @click="addTodo()" class="btn btn-primary btn-sm">追加</button>
</p>
</div>
const app = new Vue({
data: {
todoText: '',
todos: [
{text: 'Vue.jsを学ぶ', done: true},
{text: 'Vue.jsでアプリケーションをつくる', done: false},
]
},
computed: {
remaining() {
const count =
this.todos.reduce((count, todo) =>
count = (todo.done) ? count : ++count
, 0);
return count;
}
},
methods: {
addTodo() {
const newTodo = this.todoText.trim();
this.todoText = '';
if (!newTodo) {return;}
this.todos = [
...this.todos,
{text: newTodo, done: false}
];
},
archive() {
this.todos = this.todos.filter((todo) => !todo.done);
}
}
});
document.addEventListener('DOMContentLoaded', () =>
app.$mount('#app')
);
03 項目に削除ボタンを加える
さらに、チェックのあるなしにかかわらず、項目ごとに消せるようにします。そのために、それぞれの項目に<button>
要素を、つぎのように加えてください(図002)。@click
ディレクティブから呼び出すメソッド(removeTodo()
)はつぎの項で定めます。注目していただきたいのは、引数に項目のデータ(todo
)を渡していることです。そうしないと、メソッドがどの項目を削除すればよいのかわかりません。
<body>要素<div id="app" class="container"> <ul class="list-unstyled"> <li v-for="todo in todos"> <button @click="removeTodo(todo)" class="btn btn-warning btn-sm">削除</button> </li> </ul> </div>
図004■それぞれの項目の右にボタンが加わった
04 ボタンクリックした項目をデータから除く
methods
オプションに加えるのは、ボタンから呼び出されるメソッド(removeTodo()
)です。クリックした項目のデータは、引数(todo
)に渡されます。すると、つぎのようにデータの配列(todos
)から、インデックスを調べて(Array.prototype.indexOf()
)取り除けばよいでしょう(Array.prototype.splice()
)。
<script>要素const app = new Vue({ methods: { removeTodo(todo) { const todos = this.todos; const index = todos.indexOf(todo); todos.splice(index, 1); }, }, });
今回は、もとのリスト項目データ(todos
)を書き替えてしまってよいので、このコードでまったく問題ありません。けれど、条件にあった要素の新たな配列をつくるArray.prototype.filter()
メソッドの方が、端的でしょう。つぎにまとめたコード002は、こちらの処理を用いました。これで、項目右のボタンを押すとチェック済みかどうかにかかわらず、データから除かれて画面から消えます。コードを試すためのサンプル001も併せて掲げます。
コード002■項目を調べてデータから削除する
<body>要素
<div id="app" class="container">
<h2>Todo</h2>
<p>
全{{todos.length}}件中残り{{remaining}}件
<button @click="archive" class="btn btn-danger btn-sm">断捨離</button>
</p>
<ul class="list-unstyled">
<li v-for="todo in todos">
<label>
<input type="checkbox" v-model="todo.done">
<span :class="{'done': todo.done}">{{todo.text}}</span>
</label>
<button @click="removeTodo(todo)" class="btn btn-warning btn-sm">削除</button>
</li>
</ul>
<p>
<input type="text" v-model="todoText" placeholder="add new todo here">
<button @click="addTodo" class="btn btn-primary btn-sm">追加</button>
</p>
</div>
const app = new Vue({
data: {
todoText: '',
todos: [
{text: 'Vue.jsを学ぶ', done: true},
{text: 'Vue.jsでアプリケーションをつくる', done: false},
]
},
computed: {
remaining() {
const count =
this.todos.reduce((count, todo) =>
count = (todo.done) ? count : ++count
, 0);
return count;
}
},
methods: {
addTodo() {
const newTodo = this.todoText.trim();
this.todoText = '';
if (!newTodo) {return;}
this.todos = [
...this.todos,
{text: newTodo, done: false}
];
},
removeTodo(todo) {
this.todos = this.todos.filter((_todo) => _todo !== todo);
},
archive() {
this.todos = this.todos.filter((todo) => !todo.done);
}
}
});
document.addEventListener('DOMContentLoaded', () =>
app.$mount('#app')
);
サンプル001■Vue.js + ES6: Removing bound data according to conditions
See the Pen Vue.js + ES6: Removing bound data according to conditions by Fumio Nonaka (@FumioNonaka) on CodePen.
Vue.js + ES6
- Vue.js + ES6入門 01: Vue.jsを始める
- Vue.js + ES6入門 02: 要素のclass属性を動的に変える
- Vue.js + ES6入門 03: データから動的にリストをつくる
- Vue.js + ES6入門 04: フィールドに入力したテキストを動的に項目として加える
- Vue.js + ES6入門 05: 項目を数えて表示する
- Vue.js + ES6入門 06: 項目を調べてデータから削除する
- Vue.js + ES6入門 07: 表示する項目をフィルタで切り替える
- Vue.js + ES6入門 08: フィルタをボタンで切り替える
- Vue.js + ES6入門 09: アプリケーションをコンポーネントに分ける
- Vue.js + ES6入門 10: コンポーネントの応用とデータのチェック
- Vue.js + ES6入門 11: データチェックの応用とkey属性
- Vue.js + ES6入門 12: ローカルコンポーネントを定める
作成者: 野中文雄
作成日: 2019年6月8日 FN1702009「Vue.js入門 06: 項目を調べてデータから削除する」とFN1702010「Vue.js入門 07: データを項目ごとに削除する」を全面改訂。
Copyright © 2001-2019 Fumio Nonaka. All rights reserved.