43
57

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vue+Webpack+Sassを使ったWebアプリケーションの作り方

Posted at
1 / 14

話す内容

  1. vue-routerでのルーティング
  2. APIとの通信
  3. vue-routerでのmiddleware周り

実行環境を作る

Webpackを落としてきます。

npm install -g vue-cli
vue init webpack sample
cd sample;npm install

Sassなどを入れます。

npm install --save node-sass sass-loader axios

実行します。

npm run dev

Sassを使ってみる

  1. HelloWorld.vue を開きます。
  2. templatestyle を下記のように修正します。
<template>
  <div class="hello">

    .....

    <div class="hello__footer">
      footer
    </div>
  </div>
</template>

<style scoped lang="scss">

.....

.hello {
  &__footer{
    color: #00f
  }
}
</style>

style で、lang="scss" と指定すると、Sassが使えます。


フォルダ構造

下記のようになっています。
基本的に使うのは、 src/ ディレクトリ配下です。
完全に共通して使うものは、 index.html に書きましょう。

tree -L 2
.
├── README.md
├── build
│   ├── build.js
│   ├── check-versions.js
│   ├── dev-client.js
│   ├── dev-server.js
│   ├── utils.js
│   ├── vue-loader.conf.js
│   ├── webpack.base.conf.js
│   ├── webpack.dev.conf.js
│   ├── webpack.prod.conf.js
│   └── webpack.test.conf.js
├── config
│   ├── dev.env.js
│   ├── index.js
│   ├── prod.env.js
│   └── test.env.js
├── index.html
├── node_modules
├── package-lock.json
├── package.json
├── src
│   ├── App.vue
│   ├── assets
│   ├── components
│   ├── main.js
│   └── router
├── static
└── test
    ├── e2e
    └── unit

Bootstrapの追加といらないものの削除

index.html に下記のように修正。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>sample</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
  </body>
</html>

app.vue を下記のように修正

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
#app {}
</style>

ルーティング

router/index.js でルーティングできます。
そのまえに、src/pagessrc/pages/Home ディレクトリを作成し、 Home.vue, home.html, home.scss ファイルを追加しましょう。
そして、 下記のように実装します。

Home.vue
<template src="./home.html"></template>
<style lang="scss" src="./home.scss"></style>
<script>
  export default {}
</script>
home.html
<div class="home">
	<div class="container">
		home
	</div>
</div>

そして、 index.html を下記のように修正します。

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/pages/Home/Home'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: HelloWorld
    },
    {
      path: '/home',
      name: 'Home',
      component: Home
    }
  ]
})

これで、 /home のURIをルーティングできました。


APIと通信する

今回は axios を使ってリクエストを投げます。
エンドポイントは、configディレクトリ配下のファイルを修正すると良いでしょう。
productionとdevelop環境ごとに設定できます。
下記のように、リクエストを投げたいエンドポイントを書きましょう。

dev.env.js
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')

module.exports = merge(prodEnv, {
  NODE_ENV: '"development"',
  HOME_ENDPOINT: '"http://localhost:9999/home"'
})
prod.env.js
'use strict'
module.exports = {
  NODE_ENV: '"production"',
  HOME_ENDPOINT: '"http://8.8.4.4/home"'
}

configファイルをいじった後は、dev-serverをリスタートしましょう。
再度、 npm run dev をしてください。 


次に、エンドポイントを axios を使って叩きます。
下記のように書くことで、エンドポイントからデータを取ってこれます。

<template src="./home.html"></template>
<style lang="scss" src="./home.scss"></style>
<script>
  import axios from 'axios';
  let homeEndpoint = process.env.HOME_ENDPOINT

  export default {
  	created: function() {
  		axios.get(homeEndpoint).then( response => {
  			console.log(response)
  		})
  	}
  }
</script>

ボタンのクリックでイベントを発火させたい場合は、下記のように実装することでできます。

home.html
<div class="home">
	<div class="container">
		home
		<p @click="postData('id')">button</p>
	</div>
</div>
Home.vue
<template src="./home.html"></template>
<style lang="scss" src="./home.scss"></style>
<script>
  import axios from 'axios';
  let homeEndpoint = process.env.HOME_ENDPOINT
  let postEndpoint = process.env.POST_ENDPOINT

  export default {
  	created: function() {
  		axios.get(homeEndpoint).then( response => {
  			console.log(response)
  		})
  	},
  	methods: {
  		postData: function(id) {
  			axios.post(postEndpoint, {
            	sendData: id
          	})
  		}
  	}
  }
</script>

ミドルウェア

beforeEach() でフィルターできます。
上記に書いた手順で適当にログイン画面を作り、cookieを発行するようにしてください。

下記のように修正 index.jsを実装することによって、フィルターの機能ができます。

router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Home from '@/pages/Home/Home'
import Login from '@/pages/Login/Login'
import VueCookies from 'vue-cookies'

Vue.use(Router)

let router = new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: HelloWorld
    },
    {
      path: '/home',
      name: 'Home',
      component: Home
    },
    {
      path: '/login',
      name: 'Login',
      component: Login
    }
  ]
})

router.beforeEach( (to, from, next) => {
  switch (to.path) {
    case '/home':
      if( VueCookies.get('uid') == 'sampleUid' ) {
        next()
      } else {
        next('/login')
      }
      break;
    default:
      next()
      break
  }
})


export default router

また、ログインが成功した後にリダイレクトしたい場合は、this.$router.push('/home') のように記述することでリダイレクトできます。

  import VueCookies from 'vue-cookies'

  export default {
  	methods: {
  		login: function() {
  			VueCookies.set('uid', 'sampleUid', '1y')
  			this.$router.push('/home')
  		}
  	}
  }

まとめ

  • vuejs-templatesのwebpackめっちゃ便利
  • ガード周りもう少し綺麗に書けたら最高
43
57
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
43
57

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?