LoginSignup
27
32

More than 5 years have passed since last update.

Vue.jsとVuexとvue-routerとwebpackで単一ファイルコンポーネント化してTodoListを作ってみた

Last updated at Posted at 2017-09-18

はじめに

前回の「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-routerscriptsdev-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-viewtodoInputView.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の導入自体は難しくなくすんなりできた。

27
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
32