HTML5テクニカルノート
Vue.js + ES6入門 04: フィールドに入力したテキストを動的に項目として加える
- ID: FN1906001
- Technique: HTML5 / ECMAScript 2015
- Library: Vue.js 2.6.10
Vue.jsは、入力とアプリケーションの状態を結びつける双方向バインディングが簡単にできます。入力したテキストを項目リストのデータに追加すれば、ページのリストも書き替わって項目が加わるのです。
01 入力フィールドに追加ボタンを加える
「Vue.js入門 03: データから動的にリストをつくる」でつくったコード001「複数のデータから要素をつくってリストとして差し込む」に手を加えてゆきましょう。アプリケーションに納めた複数のデータがリストとして示され、入力フィールドのテキストは初めの項目とバインディングされています(図001)。これを、入力フィールドからデータに項目が加えられるように書き替えます。
図001■入力フィールドのテキストがページの項目にバインディングされる
入力フィールドの右に、つぎのように「追加」の<button>
要素を加えます(図002)。入力フィールドの<input type="text">
要素のv-model
ディレクティブには新たなプロパティ(todoText
)を与え、以下のようにVue()
コンストラクタに渡す引数オブジェクトのdata
プロパティに加えました。
<body>要素<div id="app" class="container"> <p> <!--<input type="text" v-model="todos[0].text" placeholder="add new todo here">--> <input type="text" v-model="todoText" placeholder="add new todo here"> <button class="btn btn-primary btn-sm">追加</button> </p> </div>
<script>要素const app = new Vue({ data: { todoText: '', todos: [ ] } });
図002■入力フィールドの右に「追加」ボタンが加わった
02 入力フィールドの項目をデータに加える
「追加」ボタンをクリックしたら、入力フィールドのテキストを項目としてデータ配列に加えましょう。v-on
ディレクティブはコロン(:
)のあとに添えたイベントに、リスナーが定められます。クリックのイベントはclick
です。つぎのようにメソッド(addTodo()
)を呼び出すことにします。
<body>要素<div id="app" class="container"> <p> <button v-on:click="addTodo" class="btn btn-primary btn-sm">追加</button> </p> </div>
メソッド(addTodo()
)は、Vue()
コンストラクタに渡す引数オブジェクトのmethods
オプションに、つぎのように定めます。定義に用いた構文は、ECMAScript 2015の省略表記です。入力フィールドのテキストにバインディングされたプロパティ(todoText
)の値を、データ配列(todos
)に項目オブジェクトとして加え、フィールドは空にしました。
<script>要素const app = new Vue({ data: { todoText: '', todos: [ ] }, methods: { addTodo() { const newTodo = this.todoText; this.todoText = ''; this.todos.push( {text: newTodo, done: false} ); } } });
これで「追加」ボタンを押すと入力フィールドのテキストがデータに項目として加わり、ページのリストは改められます(図003)。もっとも、テキストとして空白スペースだけ入れても、項目に加えられてしまうのは問題です。そこで、つぎのようにString.prototype.trim()
メソッドを用いて、テキストの前後も含めて余分なスペースの入力は除き、そのうえで空白ならそこで処理は止めるようにしました。<body>
要素と<script>
要素の記述は、以下のコード001のとおりです。
<script>要素const app = new Vue({ methods: { addTodo: function() { const newTodo = this.todoText.trim(); if (!newTodo) {return;} } } });
図003■「追加」ボタンで入力フィールドのテキストがリスト項目に加わる
コード001■入力フィールドのテキストを「追加」ボタンでページのリスト項目に加える
<body>要素
<div id="app" class="container">
<h2>Todo</h2>
<ul class="list-unstyled">
<li v-for="todo in todos">
<label>
<input type="checkbox" v-model="todo.done">
<span v-bind:class="{'done': todo.done}">{{todo.text}}</span>
</label>
</li>
</ul>
<p>
<input type="text" v-model="todoText" placeholder="add new todo here">
<button v-on: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},
]
},
methods: {
addTodo() {
const newTodo = this.todoText.trim();
this.todoText = '';
if (!newTodo) {return;}
this.todos.push(
{text: newTodo, done: false}
);
}
}
});
document.addEventListener('DOMContentLoaded', () =>
app.$mount('#app')
);
03 Vueディレクティブの省略記法とECMAScript 2015のスプレッド構文を使う
Vue.jsのアプリケーションには、必ずといってよいほど用いられるディレクティブがふたつあります。v-bind:
とv-on:
です。そのため、つぎのような省略記法が用意されています。これらを使えば、前掲コード001は以下のように簡略に書けるのです。
v-bind:
→:
v-on:
→@
<body>要素<div id="app" class="container"> <ul class="list-unstyled"> <li v-for="todo in todos"> <!--<span v-bind:class="{'done': todo.done}">{{todo.text}}</span>--> <span :class="{'done': todo.done}">{{todo.text}}</span> </li> </ul> <p> <!--<button v-on:click="addTodo" class="btn btn-primary btn-sm">追加</button>--> <button @click="addTodo" class="btn btn-primary btn-sm">追加</button> </p> </div>
スプレッド構文...
は、配列から取り出した要素を関数の引数や配列リテラルの要素の組として扱います(「JavaScript: ECMAScript 2015のスプレッド構文・残余引数・分割代入を使ってみる」「スプレッド構文」参照)。いわば、配列の角かっこ[]
を取り去って、カンマ(,
)区切りの値にしてしまうということです。配列のコピーをつくったり、複数の配列をつなげたりすることが簡単にできます。大きな特長は、もとの配列を書き替えないということです。つぎのコードのように、Array.prototype.push()
メソッドの替わりにも使えます。もっとも、この場合はもとの配列(todos
)を上書きしますので、あえて使わなくても構いません。
<script>要素const app = new Vue({ methods: { addTodo() { // this.todos.push( this.todos = [ ...this.todos, {text: newTodo, done: false} ]; // ); } } });
前掲コード001を書き改めたのが、つぎのコード002です。アプリケーションの動きは変わりません。動きが確かめられるように、以下にサンプル002を掲げました。
コード002■Vueディレクティブの省略記法とECMAScript 2015のスプレッド構文を使う
<body>要素
<div id="app" class="container">
<h2>Todo</h2>
<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},
]
},
methods: {
addTodo() {
const newTodo = this.todoText.trim();
this.todoText = '';
if (!newTodo) {return;}
this.todos = [
...this.todos,
{text: newTodo, done: false}
];
}
}
});
document.addEventListener('DOMContentLoaded', () =>
app.$mount('#app')
);
サンプル001■Vue.js + ES6: Adding text in a input field to the list
See the Pen Vue.js + ES6: Adding text in a input field to the list 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月1日 FN1702007「Vue.js入門 04: フィールドに入力したテキストを動的に項目として加える」を全面改訂。
Copyright © 2001-2019 Fumio Nonaka. All rights reserved.