Vue.js2を使用してTo-Doアプリを構築する
序章
Vueは、強力なWebアプリケーションを段階的に構築するために使用できるシンプルで最小限のプログレッシブJavaScriptフレームワークです。
Vueは、AngularJSなどの他のJavaScriptフレームワークの軽量な代替手段です。 HTML、CSS、およびJSの中間的な理解があれば、Vueを起動して実行する準備ができているはずです。
この記事では、Vueが提供する素晴らしいバンドルを強調しながら、Vueを使用してToDoアプリケーションを構築します。
始めましょう!
前提条件
開始するには、VueCLIが必要です。 CLIは、シングルページアプリケーションを迅速にスキャフォールディングする手段を提供し、すぐにアプリをホットリロード、lint-on-save、および本番環境対応のビルドで実行できるようになります。
Vue CLIは、Vueアプリとコンポーネントをジャンプスタートするためのゼロ構成開発ツールを提供します。
将来のアプリの拡張方法に関して行う必要のある多くの決定が処理されます。 Vue CLIには、すぐに使用できる自給自足のパッケージを提供する一連のテンプレートが付属しています。 現在利用可能なテンプレートは次のとおりです。
webpack
-ホットリロード、リンティング、テスト、CSS抽出を備えたフル機能のWebpack+Vueローダーのセットアップ。webpack-simple
-迅速なプロトタイピングのためのシンプルなWebpack+Vueローダーのセットアップ。browserify
-ホットリロード、リンティング、ユニットテストを備えたフル機能のBrowserify+vueifyセットアップ。browserify-simple
-迅速なプロトタイピングのためのシンプルなBrowserify+vueifyセットアップ。simple
-単一のHTMLファイルで可能な最も単純なVueセットアップ
簡単に言えば、VueCLIはアプリを起動して実行するための最速の方法です。
- # install vue-cli
- npm install --global vue-cli
このチュートリアルでは、インスタンスではなく単一ファイルコンポーネントの使用に焦点を当てます。 また、親コンポーネントと子コンポーネントの使用方法、およびそれらの間のデータ交換についても触れます。 単一ファイルのコンポーネントを使用する場合、Vueの学習曲線は特に穏やかです。 さらに、コンポーネントに関するすべてを1か所に配置できます。 大規模なアプリケーションで作業を開始すると、再利用可能なコンポーネントを作成できるようになり、命の恩人になります。
Vue2アプリケーションの作成
次に、CLIを使用してVueアプリをセットアップします。
- # create a new project using the "webpack" template
- vue init webpack todo-app
プロジェクト名、説明、作成者、およびVueビルドを入力するように求められます。 アプリにVue-routerをインストールしません。 また、リンティングとテストのオプションまたはアプリを有効にする必要があります。 以下の私の例に従うことができます。
アプリを初期化したら、必要な依存関係をインストールする必要があります。
- # install dependencies and go!
- cd todo-app
- npm install
アプリを提供するには、次のコマンドを実行します。
- npm run dev
これにより、すぐにブラウザが開き、次のように表示されます。 http://localhost:8080
. ページは次のようになります。
アプリケーションのスタイルを設定するには、Semanticを使用します。 Semanticは、人間に優しいHTMLを使用して美しく応答性の高いレイアウトを作成するのに役立つ開発フレームワークです。 また、 Sweetalert を使用して、ユーザーにアクションの確認を促します。 Sweetalertは、デフォルトのJavaScriptアラートの美しい代替手段を提供するライブラリです。 縮小されたJavaScriptおよびCSSスクリプトとリンクを index.html
フォルダ構造のルートにあるファイル。
<!-- ./index.html -->
<head>
<meta charset="utf-8">
<title>todo-app</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.7/semantic.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert/1.1.3/sweetalert.min.js"></script>
</head>
コンポーネント構造
すべてのVueアプリには、アプリケーション全体のフレームワークとして機能するトップレベルのコンポーネントが必要です。 このアプリケーションでは、メインコンポーネントがあり、その中にネストされているのは TodoList
成分。 この中には Todo
サブコンポーネント。
メインアプリコンポーネント
アプリケーションの構築に飛び込みましょう。 まず、メインのトップレベルコンポーネントから始めます。 Vue CLIは、次の場所にあるメインコンポーネントをすでに生成しています。 src/App.vue
. その他の必要なコンポーネントを構築します。
コンポーネントの作成
VueCLIはコンポーネントを作成します Hello
セットアップ中に見つけることができます src/components/Hello.vue
. と呼ばれる独自のコンポーネントを作成します TodoList.vue
もうこれは必要ありません。
新しいの内部 TodoList.vue
ファイルには、次のように記述します。
<template>
<div>
<ul>
<li> Todo A </li>
<li> Todo B </li>
<li> Todo C </li>
</ul>
</div>
</template>
<script type="text/javascript">
export default {
};
</script>
<style>
</style>
コンポーネントファイルは3つの部分で構成されています。 テンプレート、コンポーネントクラス、およびスタイルのセクション。
テンプレート領域は、コンポーネントの視覚的な部分です。 テンプレートの動作、イベント、およびデータストレージは、クラスによって処理されます。 スタイルセクションは、テンプレートの外観をさらに改善するのに役立ちます。
コンポーネントのインポート
作成したコンポーネントを利用するには、それをメインコンポーネントにインポートする必要があります。 の中に src/App.vue
スクリプトセクションのすぐ上とテンプレートの終了タグの下に次の変更を加えます。
// add this line
import TodoList from './components/TodoList'
// remove this line
import Hello from './components/Hello'
また、参照する必要があります TodoList
componentsプロパティのcomponentを使用して、以前の参照を削除します。 Hello
成分。 変更後、スクリプトは次のようになります。
<script>
import TodoList from './components/TodoList';
export default {
components: {
// Add a reference to the TodoList component in the components property
TodoList,
},
};
</script>
コンポーネントをレンダリングするには、HTML要素のようにコンポーネントを呼び出します。 コンポーネントの単語は、キャメルケースの代わりに以下のようにダッシュで区切られます。
<template>
<div>
// Render the TodoList component
// TodoList becomes
<todo-list></todo-list>
</div>
</template>
変更を保存すると、基本的なアプリは次のようになります。
コンポーネントデータの追加
ToDoのリストを表示するために使用される主要コンポーネントにデータを提供する必要があります。 ToDoには3つのプロパティがあります。 The title
, project
、 と done
(ToDoが完了したかどうかを示すため)。 コンポーネントは、を使用してそれぞれのテンプレートにデータを提供します data
関数。 この関数は、テンプレート用のプロパティを持つオブジェクトを返します。 コンポーネントにデータを追加しましょう。
export default {
name: 'app',
components: {
TodoList,
},
// data function provides data to the template
data() {
return {
todos: [{
title: 'Todo A',
project: 'Project A',
done: false,
}, {
title: 'Todo B',
project: 'Project B',
done: true,
}, {
title: 'Todo C',
project: 'Project C',
done: false,
}, {
title: 'Todo D',
project: 'Project D',
done: false,
}],
};
},
};
主成分からデータを渡す必要があります TodoList
成分。 このために、 v-bind
指令。 ディレクティブは、ディレクティブ名の後にコロンで示される引数を取ります。 私たちの議論は、 v-bind
要素のtodos属性を式todosの値にバインドするディレクティブ。
<todo-list v-bind:todos="todos"></todo-list>
ToDoは、 TodoList
コンポーネントとして todos
. 変更する必要があります TodoList
このデータにアクセスするためのコンポーネント。 The TodoList
コンポーネントは、使用時に受け入れるプロパティを宣言する必要があります。 これを行うには、コンポーネントクラスにプロパティを追加します。
export default {
props: ['todos'],
}
データのループとレンダリング
私たちの内部 TodoList
テンプレートでは、ToDoのリストをループして、完了したタスクと未完了のタスクの数も表示します。 アイテムのリストをレンダリングするには、 v-for
指令。 これを行うための構文は、次のように表されます。 v-for="item in items"
ここで、itemsはデータを含む配列であり、itemは反復される配列要素の表現です。
<template>
<div>
// JavaScript expressions in Vue are enclosed in double curly brackets.
<p>Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p>
<p>Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p>
<div class='ui centered card' v-for="todo in todos">
<div class='content'>
<div class='header'>
{{ todo.title }}
</div>
<div class='meta'>
{{ todo.project }}
</div>
<div class='extra content'>
<span class='right floated edit icon'>
<i class='edit icon'></i>
</span>
</div>
</div>
<div class='ui bottom attached green basic button' v-show="todo.done">
Completed
</div>
<div class='ui bottom attached red basic button' v-show="!todo.done">
Complete
</div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['todos'],
};
</script>
Todoの編集
よりクリーンなコードのために、todoテンプレートを独自のコンポーネントに抽出してみましょう。 新しいコンポーネントファイルを作成します Todo.vue
の src/components
ToDoテンプレートを転送します。 ファイルは次のようになります。
<template>
<div class='ui centered card'>
<div class='content'>
<div class='header'>
{{ todo.title }}
</div>
<div class='meta'>
{{ todo.project }}
</div>
<div class='extra content'>
<span class='right floated edit icon'>
<i class='edit icon'></i>
</span>
</div>
</div>
<div class='ui bottom attached green basic button' v-show="todo.done">
Completed
</div>
<div class='ui bottom attached red basic button' v-show="!todo.done">
Complete
</div>
</div>
</template>
<script type="text/javascript">
export default {
props: ['todo'],
};
</script>
の中に TodoList
コンポーネントはコードをリファクタリングしてレンダリングします Todo
成分。 また、ToDoがに渡される方法を変更する必要があります Todo
成分。 使用できます v-for
他の要素と同じように、作成するコンポーネントの属性。 構文は次のようになります。 <my-component v-for="item in items" :key="item.id"></my-component>
.
2.2.0以降では、 key
使用時に必要です v-for
コンポーネント付き。
注意すべき重要な点は、コンポーネントには独自の分離されたスコープがあるため、これによってデータがコンポーネントに自動的に渡されないことです。 データを渡すには、小道具を使用する必要があります。
<my-component v-for="(item, index) in items" v-bind:item="item" v-bind:index="index">
</my-component>
リファクタリング TodoList
コンポーネントテンプレート:
<template>
<div>
<p>Completed Tasks: {{todos.filter(todo => {return todo.done === true}).length}}</p>
<p>Pending Tasks: {{todos.filter(todo => {return todo.done === false}).length}}</p>
// we are now passing the data to the todo component to render the todo list
<todo v-for="todo in todos" v-bind:todo="todo"></todo>
</div>
</template>
<script type = "text/javascript" >
import Todo from './Todo';
export default {
props: ['todos'],
components: {
Todo,
},
};
</script>
にプロパティを追加しましょう Todo
と呼ばれるコンポーネントクラス isEditing
. これは、 Todo
編集モードかどうか。 テンプレートの編集スパンにイベントハンドラーがあります。 これにより、 showForm
クリックされたときのメソッド。 これにより、 isEditing
プロパティをtrueにします。 それを見る前に、フォームを追加し、条件を設定して、todoまたは編集フォームを表示するかどうかに応じて設定します isEditing
プロパティは true
また false
. テンプレートは次のようになります。
<template>
<div class='ui centered card'>
// Todo shown when we are not in editing mode.
<div class="content" v-show="!isEditing">
<div class='header'>
{{ todo.title }}
</div>
<div class='meta'>
{{ todo.project }}
</div>
<div class='extra content'>
<span class='right floated edit icon' v-on:click="showForm">
<i class='edit icon'></i>
</span>
</div>
</div>
// form is visible when we are in editing mode
<div class="content" v-show="isEditing">
<div class='ui form'>
<div class='field'>
<label>Title</label>
<input type='text' v-model="todo.title" />
</div>
<div class='field'>
<label>Project</label>
<input type='text' v-model="todo.project" />
</div>
<div class='ui two button attached buttons'>
<button class='ui basic blue button' v-on:click="hideForm">
Close X
</button>
</div>
</div>
</div>
<div class='ui bottom attached green basic button' v-show="!isEditing &&todo.done" disabled>
Completed
</div>
<div class='ui bottom attached red basic button' v-show="!isEditing && !todo.done">
Pending
</div>
</div>
</template>
に加えて showForm
メソッドを追加する必要があります hideForm
キャンセルボタンがクリックされたときにフォームを閉じるメソッド。 スクリプトがどのようになるか見てみましょう。
<script>
export default {
props: ['todo'],
data() {
return {
isEditing: false,
};
},
methods: {
showForm() {
this.isEditing = true;
},
hideForm() {
this.isEditing = false;
},
},
};
</script>
フォームの値をtodo値にバインドしたので、値を編集するとすぐにtodoが編集されます。 完了したら、閉じるボタンを押して、更新されたToDoを確認します。
Todoの削除
削除するアイコンを追加することから始めましょう Todo
編集アイコンのすぐ下。
<template>
<span class='right floated edit icon' v-on:click="showForm">
<i class='edit icon'></i>
</span>
/* add the trash icon in below the edit icon in the template */
<span class='right floated trash icon' v-on:click="deleteTodo(todo)">
<i class='trash icon'></i>
</span>
</template>
次に、アイコンのクリックを処理するメソッドをコンポーネントクラスに追加します。 このメソッドはイベントを発行します delete-todo
親に TodoList
コンポーネントと現在のパス Todo
削除します。 削除アイコンにイベントリスナーを追加します。
<span class='right floated trash icon' v-on:click="deleteTodo(todo)">
// Todo component
methods: {
deleteTodo(todo) {
this.$emit('delete-todo', todo);
},
},
親コンポーネント(TodoList
)削除を処理するためのイベントハンドラーが必要になります。 それを定義しましょう。
// TodoList component
methods: {
deleteTodo(todo) {
const todoIndex = this.todos.indexOf(todo);
this.todos.splice(todoIndex, 1);
},
},
The deleteTodo
メソッドは、次のようにTodoコンポーネントに渡されます。
// TodoList template
<todo v-on:delete-todo="deleteTodo" v-for="todo in todos" v-bind:todo="todo"></todo>\
削除アイコンをクリックすると、イベントが発行されて親コンポーネントに伝播され、親コンポーネントが削除します。
新しいTodoを追加する
新しいtodoを作成するには、まずCreateTodoで新しいコンポーネントを作成します。 src/components
. これにより、クリックするとフォームに変わるプラス記号の付いたボタンが表示されます。 このように見えるはずです。
<template>
<div class='ui basic content center aligned segment'>
<button class='ui basic button icon' v-on:click="openForm" v-show="!isCreating">
<i class='plus icon'></i>
</button>
<div class='ui centered card' v-show="isCreating">
<div class='content'>
<div class='ui form'>
<div class='field'>
<label>Title</label>
<input v-model="titleText" type='text' ref='title' defaultValue="" />
</div>
<div class='field'>
<label>Project</label>
<input type='text' ref='project' defaultValue="" />
</div>
<div class='ui two button attached buttons'>
<button class='ui basic blue button' v-on:click="sendForm()">
Create
</button>
<button class='ui basic red button' v-on:click="closeForm">
Cancel
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
titleText: '',
projectText: '',
isCreating: false,
};
},
methods: {
openForm() {
this.isCreating = true;
},
closeForm() {
this.isCreating = false;
},
sendForm() {
if (this.titleText.length > 0 && this.projectText.length > 0) {
const title = this.titleText;
const project = this.projectText;
this.$emit('create-todo', {
title,
project,
done: false,
});
this.newTodoText = '';
}
this.isCreating = false;
},
},
};
</script>
新しいコンポーネントを作成したら、それをインポートして、コンポーネントクラスのcomponentsプロパティに追加します。
// Main Component App.vue
components: {
TodoList,
CreateTodo,
},
また、新しいToDoを作成するためのメソッドを追加します。
// App.vue
methods: {
addTodo(title) {
this.todos.push({
title,
done: false,
});
},
},
CreateTodoコンポーネントは、App.vueテンプレートで次のように呼び出されます。
<create-todo v-on:add-todo="addTodo">
Todoを完了する
最後に、メソッドを追加します completeTodo
に Todo
イベントを発行するコンポーネント complete-todo
保留中のボタンがクリックされたときに親コンポーネントに移動し、の完了ステータスを設定します todo
に true
.
// Todo component
methods: {
completeTodo(todo) {
this.$emit('complete-todo', todo);
},
}
イベントハンドラーがに追加されます TodoList
イベントを処理するコンポーネント。
methods: {
completeTodo(todo) {
const todoIndex = this.todos.indexOf(todo);
this.todos[todoIndex].done = true;
},
},
合格するには TodoList
方法 Todo
コンポーネントに追加します Todo
コンポーネントの呼び出し。
<todo v-on:delete-todo="deleteTodo" v-on:complete-todo="completeTodo" v-for="todo in todos" :todo.sync="todo"></todo>
結論
VueCLIを使用してVueアプリを初期化する方法を学びました。 さらに、コンポーネントの構造、コンポーネントへのデータの追加、イベントリスナー、およびイベントハンドラーについて学習しました。 ToDoを作成し、編集し、削除する方法を見ました。 学ぶべきことはまだたくさんあります。 主要コンポーネントでは静的データを使用しました。 次のステップは、サーバーからデータを取得し、それに応じて更新することです。 これで、インタラクティブなVueアプリケーションを作成する準備が整いました。 自分で何か他のことを試して、それがどうなるかを見てください。 乾杯!