はじめに
前回の「Vue.jsとVuexとwebpackで単一ファイルコンポーネント化してTodoListを作ってみた」にvue-routerをいれて、Single Page Applicationにしてみたので書いていきます。
※タイトルがどんどん長くなる・・・
機能は前回と同じく「追加」と、「完了」と、「完了から戻す」3つだけ。
Vue.jsとVuexとwebpackと単一ファイルコンポーネントの簡単な説明は前回のQiitaに書いたので割愛。
スペック
- vue-routerは少しだけ使ったことある
- SPAっぽいものを実装した経験がある
vue-router
Vue.jsでSPAを作る際のライブラリ。
router-link
vue-routerでリンクを作成するコンポーネント。
aタグのようなもの
<router-link to="/foo">Go to Foo</router-link>
router-view
SPAで書き換わる中身のコンポーネント。
下記例ではfooやbarに遷移するとrouter-view
は書き換わるがh1とかは書き替わらない。
<div id="app">
<h1>Hello App!</h1>
<p>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<router-view></router-view>
</div>
ソースコード解説
package.json
{
"name": "vuex-webpack-components-vue-router-todo-sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack",
"dev-watch": "webpack --watch"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"vue": "^2.4.2",
"vue-router": "^2.7.0",
"vuex": "^2.4.0"
},
"devDependencies": {
"css-loader": "^0.28.7",
"vue-loader": "^13.0.4",
"vue-template-compiler": "^2.4.2",
"webpack": "^3.5.6"
}
}
前回から追加したものはvue-router
とscripts
にdev-watch
を追加しました。
今まではビルドの度に毎回webpackを動かしていましたが、watchオプションをつけ自動でビルドさせています。
webpack.config.js
前回と差分なし
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Vuex Vue-Router Components Todo Sample</title>
<link rel="stylesheet" href="">
<style>
main {
display: flex;
}
</style>
</head>
<body>
<div id="app">
<header>
<router-link to="todoInput">Go to TodoInput</router-link>
<router-link to="todoList">Go to todoList</router-link>
<router-link to="doneList">Go to doneList</router-link>
</header>
<router-view></router-view>
</div>
<script src="js/bundle.js"></script>
</body>
</html>
router-link
コンポーネントを利用し、3つのリンクを作成。
また、router-view
コンポーネントを記述しています。
app.js
import Vue from 'vue';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
import routes from './router/routes.js';
import actions from './action/actions.js';
import mutations from './mutation/mutations.js';
Vue.use(Vuex);
Vue.use(VueRouter);
var store = new Vuex.Store({
state: {
todos: [],
dones: []
},
getters: {
todos(state) {
return state.todos;
},
dones(state) {
return state.dones;
}
},
actions: actions,
mutations: mutations,
});
const router = new VueRouter({
routes
});
new Vue({
el: '#app',
store: store,
router: router,
});
すっきりとしたJSに!
actionsとmutationsはそのまま別JSファイルに出しました。
※stateとgettersも出したほうが良い気がしたが今回はそのまま
VueRouterの引数にroutesを渡して生成し、Vueに渡してvue-routerの設定は終わり。
routes.js
import indexView from './../view/indexView.vue';
import todoInputView from './../view/todoInputView.vue';
import todoListView from './../view/todoListView.vue';
import doneListView from './../view/doneListView.vue';
export default [
{ path: '/', component: indexView },
{ path: '/todoInput', component: todoInputView },
{ path: '/todoList', component: todoListView },
{ path: '/doneList', component: doneListView },
];
今回のメインのvue-routerのルーティング設定ファイル。
vue-routerの公式は一つのJSに書かれていますが、今回は別ファイルにしました。
各URLとコンポーネントを紐付けています。
/todoInput
にアクセスすると、router-view
にtodoInputView.vue
が表示されます。
todoInputView.vue
<template>
<section class="wrap">
<h2>Todo Input</h2>
<todo-input></todo-input>
</section>
</template>
<style scoped>
.wrap {
padding: 0 10px;
}
</style>
<script>
import todoInput from './../components/todoInput.vue';
export default {
components: {
todoInput
},
}
</script>
単一ファイルコンポーネント。
todoInput.vue
をimportし<template>
内で表示しています。
todoInput.vue
<template>
<input type="text" @keyup.enter="addTodoText"/>
</template>
<script>
export default {
methods: {
addTodoText(e) {
var text = e.target.value;
this.$store.dispatch('addTodo', {
text: text
});
e.target.value = '';
}
}
}
</script>
input
要素と挙動だけ書かれた単一ファイルコンポーネント。
所感
vue-roterの導入自体は難しくなくすんなりできた。