11月16日 Web Application 製作入門
富山IT勉強会#4 のハンズオン資料をまとめたものです。
非エンジニア、およびWebアプリ未経験者を対象に簡単なWebアプリ(SPA)を作成するハンズオンを行います。
このハンズオンのゴール(目的)
- 必要最低限の知識で Webアプリを作れるようになる(概念、環境構築 ~ Local環境での動作確認)
- 今後、更にレベルアップしていく際の切り口を共有する
おことわり
一日(4h ほど)で行う予定であるため、最低限知っていれば取りあえずアプリが作れる程度に厳選しております。
そのため、かなり内容は端折っておりますのでご了承ください。
また、私自身プログラミング経験はWindowsアプリケーションがほとんどで、
Web関係は直近一年弱程度ですので情報にはかなり偏りがあります。
また、誤情報等、お気付きの場合にはご指摘頂けると幸いです。
やること
- JavaScript入門(環境構築〜変数、制御構文、クラス、関数を最小限、簡単に。npmコマンドにもふれる)
- Node.js、Vue を使用したWebアプリケーションを作成(Vue基本構文, Vue/Cliコマンド)
- expressを使用したWebAPIの作成とWebアプリとの通信(express 最小構成でのWebAPIサーバー構築)
- 時間があった時のオプション
- PythonでもWebAPIを作成してみる(Flask 最小構成)
- -> AI 機能を組み込んだWebAPIへ応用可?
- Electronを使用したデスクトップアプリ化(electron-vueを使用)
- -> Web技術を使用したデスクトップアプリ開発へ繋げたい場合
- CSSフレームワークを使用してみる(vuetify)
- -> もっと見た目をきれいに、機能的にしたい場合
- PythonでもWebAPIを作成してみる(Flask 最小構成)
やらないこと
- formタグを使ったGet、Post等の通信
- yarn
- 本番環境へのデプロイ(ローカル環境でのみの作業とします)
- セキュリティ関連
- DataBase操作
1. Web(Server - Client 型アプリケーション) の仕組み
本当にザックリですが図を作ってみました。
Webサイト、Webアプリなどは、このClient-Server型のアプリケーションになります。
Client Side はChrome等のブラウザを通してサーバーへリクエストを行います。
サーバーPCの中では、この時Apache等のサーバーアプリやデータベースが起動していて、
リクエストに応じた処理を行い、結果をHtmlファイルやJson等で返信します(レスポンス)。
今回は、この図でいうバックエンドのサーバーアプリ部分をexpressで作ります。
また、レスポンスとして返すHtmlファイルを、Vueを使って作成します。
2. 環境構築
Node.jsのインストール
nodejs.org :https://nodejs.org/ja/からLTS版をダウンロード。
ダウンロードされたインストーラーを実行してインストールを行ってください。
インストール完了後、以下のコマンドをshellへ入力して、バージョンが返ってきたらOK。
node -v
npm -v
visual studio code (vscode) のインストール
vscodeを用いてハンズオンを行いますが、お気に入りのエディタがある場合はそちらを使っていただいてもかまいません。
https://code.visualstudio.com/download から自分のOSに合わせたインストーラーをダウンロードし、インストールを行ってください。
3. JavaScript(というかNode.js)入門
まずはhello world
const msg = 'hello world';
console.log(msg);
node ./hello.js
=> hello world
変数の型(es6)
今回使用するもののみピックアップ。
Number
数値型。C#やPython等では整数型(Int)、浮動小数点型(Float)等あったがjsはこれだけ
const pi = 3.14;
var index = 1;
String
文字列型
const message = 'hello world'; // '' で囲む
var name = "huga"; // "" もOK
Boolean
true
or false
const flg = true;
console.log(flg); // => true
console.log(!flg); // => false
if(flg) {
console.log('flg is true'); // => flg is true
}
Array(配列)
配列。どちらかというとリストに近いような...
// 宣言方法
const arr = []; // arr => [](空配列)
let values = new Array(); // values => [](空配列)
const arr2 = [1,2,3]; // arr2 => [1,2,3]
const values2 = new Array(5); // values => [ <5 empty items> ] (5要素の配列)
console.log(values2[1]); // => undefined
// 要素の追加
arr.push(1);
arr.push(2);
console.log(arr); // => [1,2]
// 要素の参照
console.log(arr[0]); // => 1
console.log(arr[1]); // => 2
// 要素の取り出し
console.log(arr.pop()); // => 2
console.log(arr); // => [1]
Function
関数
// 通常?の宣言
function twice(num) {
return num * 2;
}
// ラムダ式
const joinStr = (str1, str2) => { return str1 + str2; };
console.log(twice(2)); // 4
console.log(joinStr("hello ", "world")); // hello world
Object
オブジェクト、連想配列。classとかもes5ではオブジェクトになる?? keyに対して任意のデータを割り当てる
// 宣言
const obj = {};
const obj2 = new Object();
// 要素の追加
obj["id"] = 1;
obj.name = "huga";
obj.getName = function() {
return this.name;
};
console.log(obj); // => { id: 1, name: 'huga', getName: [Function] }
// 要素の参照
console.log(obj["id"]); // => 1
console.log(obj.name); // => huga
console.log(obj.getName()); // => huga
null, undefined
null は他の言語と大体同じ?参照先が未割当の状態。
undefined はそもそも項目すらない状態?(よくわかってません)
今回はここを理解していなくてもできるようにやっていきます。
const, let, var
var
変数を宣言し、ある値に初期化することもできる。グローバル変数として定義される。
let
ブロックスコープのローカル変数を宣言し、ある値に初期化することもできる。
ローカル変数(スコープ内で有効な変数)で、再代入が可能。
const
読み取り専用の名前付き定数を宣言する。
ローカル変数(スコープ内で有効な変数)で、再代入が不可能。
制御構文
if
分岐処理
let flg = false;
if (flg) {
// 実行されない
}
else {
// 実行される
}
if (flg != true) {
// 実行される
}
for
繰り返し処理
const numbers = [1,2,3,4,5];
for (let i = 0; i < numbers.length; i++) {
const element = numbers[i];
console.log(element);
// => 1
// => 2
// => 3
// => 4
// => 5
}
他にもswitch
, while
等あります。
参考リンク
4. HTML
適当なフォルダをvscodeで開いて、適当な名前.html
というファイルを作成します。
ファイル内で html
と入力すると以下のように補完が表示されると思いますので、html5
を選択します。
以下のようにテンプレートが挿入されます。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
</body>
</html>
body
タグの中にHTMLを記述していきます。
Header
見出しです。h1 ~ h6まであり、数字が小さい程基本的には表示が大きくなります。
bodyタグの中に記述して確認してみます。
<body>
<h1>h1 ヘッダーです</h1>
<h2>h2 ヘッダーです</h2>
<h3>h3 ヘッダーです</h3>
<h4>h4 ヘッダーです</h4>
<h5>h5 ヘッダーです</h5>
<h6>h6 ヘッダーです</h6>
</body>
〇結果
リスト
リストを表示します。番号付き(<ol></ol>
)と番号無し(<ul></ul>
)があります。
<body>
<!-- 番号付きリスト -->
<ol>
<li>リスト1</li>
<li>リスト2</li>
<li>リスト3</li>
<li>リスト4</li>
</ol>
<!-- 番号無しリスト -->
<ul>
<li>リスト1</li>
<li>リスト2</li>
<li>リスト3</li>
<li>リスト4</li>
</ul>
</body>
〇 結果
- リスト1
- リスト2
- リスト3
- リスト4
- リスト1
- リスト2
- リスト3
- リスト4
表
表を表示します。
<body>
<table border="1">
<tr><th>項目1</th><td>A</td></tr>
<tr><th>項目2</th><td>B</td></tr>
<tr><th>項目3</th><td>C</td></tr>
</table>
<hr>
<table border="1">
<thead>
<tr><th>キー</th><th>値</th></tr>
</thead>
<tbody>
<tr><td>項目1</td><td>A</td></tr>
<tr><td>項目2</td><td>B</td></tr>
<tr><td>項目3</td><td>C</td></tr>
</tbody>
</table>
</body>
〇 結果
項目1 | A |
---|---|
項目2 | B |
項目3 | C |
キー | 値 |
---|---|
項目1 | A |
項目2 | B |
項目3 | C |
入力要素
テキストボックスやボタン、スライダー等。
通常は<form></form>
タグの中で使用してGETやPOSTメソッドで送信に使いますが、
Vue等のフレームワークでは変数の操作に用いたりします。
<body>
<div>
<h3> テキストボックス </h3>
<input type="text">
</div>
<div>
<h3> テキストボックス(パスワード) </h3>
<input type="password">
</div>
<div>
<h3> ボタン </h3>
<input type="button" value="ボタンです">
</div>
<div>
<h3> チェックボックス </h3>
チェックしてください<input type="checkbox">
</div>
<div>
<h3> ラジオボックス </h3>
<input type="radio" name="my-radio" value="radio-item1">ラジオ1
<input type="radio" name="my-radio" value="radio-item2">ラジオ2
<input type="radio" name="my-radio" value="radio-item3">ラジオ3
</div>
<div>
<h3> コンボボックス </h3>
<select>
<option selected="0">選択アイテム1</option>
<option>選択アイテム2</option>
<option>選択アイテム3</option>
<option>選択アイテム4</option>
</select>
</div>
<div>
<h3>スライダー</h3>
<input type="range">
</div>
<div>
<h3> カラーピッカー </h3>
<input type="color">
</div>
<div>
<h3> FILE API </h3>
<input type="file" id="file-handler">
</div>
</body>
〇結果 (Chrome)
4. Vue入門
準備
Webアプリケーション フレームワークのVueを使用して作成していきます。
〇 参考リンク:
まずはHTMLファイルとスタンドアロン版のVue.js(CDN)を使用してVueの基本構文を確認します。
フォルダ内にvue-starter.html
を作成し、以下のように入力します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Vue Starter</title>
</head>
<body>
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
</div>
<!-- vue.js を読み込んでからVueオブジェクトを記載していく -->
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script>
// Vue オブジェクト
var app = new Vue({
el: '#app',
data() {
return {
// object 形式でプロパティを記述していく
};
},
// 算出プロパティ(キャッシュされる)
computed: {
},
// 監視プロパティ
watch: {
},
// 関数(キャッシュされない、都度評価される)
methods: {
},
// ライフサイクルフック ---------------------------------------------------
// https://jp.vuejs.org/v2/api/#beforeUpdate
beforeCreate() {
},
created() {
},
mounted() {
},
beforeUpdate() {
},
updated() {
},
activated() {
},
deactivated() {
},
beforeDestroy() {
},
destroyed() {
}
// ライフサイクルフック ---------------------------------------------------
});
</script>
</body>
</html>
プロパティ名 | 説明 |
---|---|
el | VueでレンダリングするHTML DOMのidを記述する。 |
data | レンダリングで参照されるプロパティ。画面描画のもとになる |
computed | dataを元に算出されるプロパティ。いわゆるgetter |
watch | 登録されているdataの変化を監視し、変更があった場合の処理を記述する |
methods | 関数。ボタンのクリックイベント等、特定のイベントにフックして実行する処理を記述する |
ライフサイクルフック
Vueが描画を行う際の特定のタイミングで呼ばれるイベント。
詳しくは以下参照。
宣言的レンダリング(プロパティの参照)
描画DOMエリアとVueオブジェクトを以下のように修正します。
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
<p>{{message}}</p>
</div>
// Vue オブジェクト
var app = new Vue({
el: '#app',
data() {
return {
// object 形式でプロパティを記述していく
message: 'Hello Vue!'
};
}
});
〇結果
繰り返しレンダリング(v-for)
配列やオブジェクトの要素を繰り返しレンダリングします。
描画DOMエリアとVueオブジェクトを以下のように修正します。
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
<p>Array のレンダリング</p>
<ul>
<li v-for="(item, index) in itemList">{{index}}: {{item}}</li>
</ul>
<p>Object のレンダリング</p>
<table border="1">
<thead>
<th>key</th><th>value</th>
</thead>
<tbody>
<tr v-for="(item, key) in obj"><td>{{key}}</td><td>{{item}}</td></tr>
</tbody>
</table>
</div>
data() {
return {
// object 形式でプロパティを記述していく
itemList: [
'huga',
'hoge',
'poyo'
],
obj: {
name: 'Vue',
id: 1,
lang: 'JavaScript'
}
};
},
イベント(v-on)
ボタンクリック等のイベントをフックして処理を実行します。
描画DOMエリアとVueオブジェクトを以下のように修正します。
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
<button v-on:click="call()">click me!!</button>
</div>
methods: {
call() {
alert('button clicked');
}
},
条件付きレンダリング(v-if, v-show)
v-if
、v-show
共に条件を満たす場合にのみレンダリングされます。
違いは、レンダリングされない場合、以下の点が異なる。
-
v-if
: レンダリングされない場合、DOMが生成されない。 -
v-show
: レンダリングされない場合もDOMが生成される。style属性がdisplay: none;
となることで表示されなくなる。
描画DOMエリアとVueオブジェクトを以下のように修正します。
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
<button @click="toggleFlg()">フラグ切り替え</button>
<p v-if="isShow == true">フラグがtrue なら描画されます</p>
</div>
data() {
return {
// object 形式でプロパティを記述していく
isShow: true
};
},
// 関数(キャッシュされない、都度評価される)
methods: {
toggleFlg() {
this.isShow = !this.isShow;
}
}
○結果
ボタンを押すたびに下部のテキストの表示、非表示が切り替わります。
算出プロパティと監視プロパティ(computed,watch)
描画DOMエリアとVueオブジェクトを以下のように修正します。
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
<h2>computed</h2>
<p>num is: {{num}}</p>
<p>twice is: {{twice}}</p>
<button @click="increment()">numへ1加算</button>
<h2>watch</h2>
<p>{{watchStr}}</p>
</div>
data() {
return {
// object 形式でプロパティを記述していく
num: 1,
watchStr: ""
};
},
// 算出プロパティ(キャッシュされる)
computed: {
twice() {
// 二乗の数を返す
return Math.pow(this.num, 2);
}
},
// 関数(キャッシュされない、都度評価される)
methods: {
increment() {
this.num++;
}
},
// 監視プロパティ
watch: {
// 関数名は監視するプロパティ名
num(newValue, oldValue) {
this.watchStr = `${oldValue} -> ${newValue}`;
}
},
form要素との連携(v-bind、v-model)
input
タグのform要素と同期してdata
を操作できます。
html部
<div id="app">
<!-- このエリアにVue 形式の HTMLを記述していく(描画DOMエリア) -->
<h2>v-model(双方向同期)</h2>
<input type="text" v-model="message">
<p>{{message}}</p>
<select v-on:input="selectedItem = $event.target.value;">
<option selected="0" v-for="item in listItems">{{item}}</option>
</select>
<p>入力値:{{selectedItem}}</p>
<!-- v-bind:r="radius" は :r="radius" と省略してもOK -->
<h2>v-bind(片方向同期)</h2>
<input type="range" v-model="radius" max="100" min="0">
<p>radius = {{radius}}</p>
<svg viewbox="0 0 300 300" width="300" height="300">
<circle v-bind:r="radius" cx=150 cy=150></circle>
</svg>
</div>
JavaScript部
data() {
return {
// object 形式でプロパティを記述していく
message: 'hello vue',
selectedItem: null,
listItems: [
"item1",
"item2",
"item3",
],
radius: 10,
};
},
○結果
Vue CLI を使ったWebアプリ(SPA)の作成
ここからfront-end、back-end に分けてWebアプリ(のようなもの)を作っていきます。
まずは、front-end側から作り始めます。
プロジェクトフォルダ作成
お好きなところにvue-spa-sample
という名前でフォルダを作ります。
vue/cliのインストール
vue-spa-sample
フォルダ内でコマンドラインを立ち上げます。
以下のコマンドでVue CLI をグローバルへインストールします。
npm i -g @vue/cli
なお、npm のコマンドは以下が纏まっていてみやすかったです。
npm 入門
インストールが終了したら以下のコマンドでバージョンが返ってくることを確認します。
vue -V
front-end プロジェクトの作成
続けてコマンドラインから
vue create front
でプロジェクトを作成します。
front
の部分はプロジェクト名になるので、
本来はお好きな名前をつけていただいてOKです。
[2019/11/18 修正]
axios が上手く動かなかったので、TypeScript で記述して行きます。
原因わかりましたらまた更新します。
以前のここのセットアップ方法はJavaScript版のものなので、
TypeScript版へ修正します。
[2019/11/20 修正]
JavaScript版でも動作確認できました。
JavaScript版でこのハンズオンを進める場合は、以下のPlease pick a preset:
でdefault(babel, eslint)
を選択します。(選択するとプロジェクトのダウンロードがすぐに始まります)。
TypeScriptを使用する場合は以下の流れで設定して行きます。
Babel
、 TypeScript
、 Linter / Formatter
を選択し、Enterを押下します。
ちなみに Babel
-> 1 、 TypeScript
-> 2 のように、
数字キーがそれぞれの要素に対応しています。
クラススタイルで記述するか?の質問です。 n を押下します。
クラススタイルは記述しやすいですが、以下のデメリットがあるため、私は通常の記述スタイルをおすすめしています。
-
<template>
タグ内で補完が効かない(vscode,vetur 使用の場合) - 挙動が異なる場合がある
- ググってヒットする情報のほとんどがJavaScriptの記述方式であり、クラススタイルを採用した場合は読み換える必要がある。
y を押下
ESLint with error prevention only
を選択して押下
Lint on save
を選択して押下
In dedicated config files
を選択して押下
n を選択して押下。
パッケージのダウンロードが始まります。
全て終了したら、表示されているように以下のコマンドを入力してdev serverを立ち上げます。
cd front
npm run serve
dev server が立ち上がったら、ブラウザからhttp://localhost:8080
へ接続します。
以下のような画面が表示されます。
確認したら、vscodeでfrontフォルダを開きます。
これからVueのSFCファイルを見て行きますが、ハイライトや補完等の機能が使えるように、
エクステンションでvetur
を検索し、インストールしておきます。
単一ファイルコンポーネント(SFC)とコンポーネント
Vue CLI で作られたプロジェクトはSFCに対応しています。
SFCとは、コンポーネント(Vueの描画領域を部分的に記述し、部品化したもの)をtemplate
、script
、css
のそれぞれのタグに分けて記述したものです。
現在のプロジェクトで言うと、src/App.vue
が画面全体を描画しているコンポーネントで、
src/components/HelloWorld.vue
は部分的リンクの部分を描画している部品になります。
コードで見るとこんな感じです。
コンポーネントを作ってみる
src/components/
内にMainPage.vue
という名前でSFCを作ります。
以下のようにコードを記述します。
(以降のコードはTypeScriptを選択した場合の記述スタイルです。JavaScriptを選択した場合は、
<script lang="ts">
を <script>
に変更してください。それ以外の部分は共通で動作します。)
<template>
<div>
<h1>自作コンポーネントのページです</h1>
<h2>hello {{name}}</h2>
</div>
</template>
<!-- JavaScriptの場合は以下のように lang="ts" を記述しない-->
<!-- <script> -->
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'main-page',
data() {
return {
name: 'vue', // 好きな名前を入れてください
}
}
});
</script>
<style>
</style>
ファイルを保存したら、src/App.vue
を以下のように修正します。
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<!-- コメント化 -->
<!-- <HelloWorld msg="Welcome to Your Vue.js App"/> -->
<!-- 追加 -->
<main-page/>
</div>
</template>
<script lang="ts">
// import HelloWorld from './components/HelloWorld.vue' // <- コメント化
import MainPage from "./components/MainPage.vue"; // <- 追加、.vue を忘れないで
export default {
name: 'app',
components: {
// HelloWorld // コメント化
MainPage // 追加
}
}
</script>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
ファイルを保存します。
再度先ほどブラウザで開いたhttp://localhost:8080
を見るとオートリロードがかかって
以下のようになっていると思います。(なっていなかったら手動でリロードしてください)
MyButton コンポーネントの追加
src/components/
内にMyButton.vue
という名前でオリジナルのボタンを作って見ます。
私はデザインはできないので、以下のサイト様からパク参考にさせて頂きました。
CSSで作る!押したくなるボタンデザイン100(Web用)
<template>
<a href="#" class="btn-square" @click="change()">{{label}}</a>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
name: 'my-button',
props: [
'label'
],
methods: {
change() {
this.$emit('label-update', 'changed');
}
}
})
</script>
<style scoped>
.btn-square {
display: inline-block;
padding: 0.5em 1em;
text-decoration: none;
background: #668ad8;/*ボタン色*/
color: #FFF;
border-bottom: solid 4px #627295;
border-radius: 3px;
}
.btn-square:active {
/*ボタンを押したとき*/
-webkit-transform: translateY(4px);
transform: translateY(4px);/*下に動く*/
border-bottom: none;/*線を消す*/
}
</style>
style
タグ内に付いているscoped
は、SFCファイル独自のもので、
記述すると定義されているCSSをこのコンポーネントのみに適用することができます。
また、Vueオブジェクト内のprops
は、コンポーネントの呼び出し側からデータを受け取ることのできるプロパティです。また、methods内のthis.$emit
は、このコンポーネント呼び出すイベントを定義しています。
具体的には、ボタンが押下されると、label-update
イベントが起き、呼び出し元の親コンポーネントへ変更された値を通知します。
(Vueでは子コンポーネントがporpを勝手に書き換えることはNGとされており、このようにイベントとして親コンポーネントに通知を送り、親オブジェクトに変更をかけてもらうようにしています。)
MainPage.vueを以下のように変更し、結果を確認して見ます。
<template>
<div>
<h1>自作コンポーネントのページです</h1>
<h2>hello {{name}}</h2>
<!-- 追加 -->
<my-button :label="btnName" @label-update="updateName"/>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import MyButton from "./MyButton.vue"; // 追加
export default Vue.extend({
name: 'main-page',
components: {
MyButton
},
data() {
return {
name: 'vue', // 好きな名前を入れてください
btnName: 'Myボタン' // 追加
}
},
// 追加
methods: {
updateName(val: string) {
this.btnName = val;
}
}
});
</script>
<style>
</style>
5. WebAPIの作成
express を使ってWebAPIを作成します。
vue-spa-sample
フォルダ内にback
フォルダを作り、その中でコマンドラインを立ち上げます。
以下のコマンドを順に打ち込んで行きます。
npm init -y
npm i -S express cors body-parser
インストールが終わったら、vscodeでback
フォルダを開きます。
back/src
フォルダ内にrouter
フォルダを作成し、その中にroot.js
ファイルを作成します。
const express = require("express");
const router = express.Router();
router.get('/', (req/* リクエスト */, res/* レスポンス */) => {
// json でレスポンス
res.send({
message: 'res from express'
});
});
module.exports = router;
back/src
フォルダ内にapp.js
ファイルを作成し、以下のコードを記述します。
const express = require("express");
const bodyparser = require("body-parser");
const cors = require("cors");
const indexRouter = require("./router/root");
const app = express();
// CORS 制限の解除
app.use(cors());
// 通信にJsonを使用する
app.use(bodyparser.json())
// /にindexRouterをルーティング
app.use('/', indexRouter);
module.exports = app; // appを公開
back/src
フォルダ内にindex.js
ファイルを作成し、以下のコードを記述します。
const app = require("./app");
const port = 3000;
app.listen(port, () => {
// port listen を始めた時に実行される処理
console.log(`express listen port ${port}`);
});
全て保存したら、コマンドラインで以下のコマンドを実行
node ./src/index.js
サーバーが起動したら、ブラウザからhttp://localhost:3000
にアクセスする。
以下のようになったらOK。
6 WebアプリとWebAPI で通信
これまで作ってきたfront-end と back-end を連携して行きます。
front側のdev-serverをctrl + c
で終了し、以下のコマンドを入力する
npm i -S axios
axiosがインストールされたら、再度
npm run serve
でdev-server を起動して起きます。
axiosで通信する
src/components/MainPage.vue
を以下のように修正します。
<template>
<div>
<h1>自作コンポーネントのページです</h1>
<h2>hello {{name}}</h2>
<my-button :label="btnName" @label-update="updateName"/>
<!-- 追加 -->
<div>
<p>{{message}}</p>
<button @click="getExpress()">get express root</button>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import MyButton from "./MyButton.vue";
import * as axios from "axios";
export default Vue.extend({
name: 'main-page',
components: {
MyButton
},
data() {
return {
name: 'vue', // 好きな名前を入れてください
btnName: 'Myボタン',
message: 'no message' // 追加
}
},
methods: {
updateName(val: string) {
this.btnName = val;
},
// 追加
getExpress() {
axios.default.get('http://localhost:3000').then((responce) => {
this.message = responce.data.message;
});
}
}
});
</script>
<style>
</style>
http://localhost:8080
にアクセスしてget express root
のボタンを推してみる。
no message
が res from express
に変わったら成功。localのexpressサーバーと通信できてます。
今後やって行くこと
- Electronでデスクトップアプリ化 Electron+Vue.jsを使ったデスクトップアプリ開発を始める手順
- CSS フレームワークを使って綺麗なデザインにする Vue-cli3からのVuetifyを試す
- python でwebサーバーを立てる ゾンビでもわかるPythonプログラミング
- 無料WebAPIを叩いてみる個人でも使える!おすすめAPI一覧