はじめに
前から気になっていたNuxt.jsを触ってみました。これ使って何かやってみようと考えた結果、
mysqlと連携させてみることにしました。Nuxt.jsに関して入門的な情報は既にいろいろと存在するので、
ここでは、そのつなぎの部分にフォーカスして記載したいと思います。
内容
下記の項目に沿って記載します。
- Nuxt.jsについて
- Nuxt.jsのインストール
- データベース準備
- 必要なモジュール
- APIの実装
- フロントエンドの実装
- 結果
- おわりに
Nuxt.jsについて
ご存知の方には恐縮ですが、Nuxt.jsはナクストと読むようであり、
Webアプリケーションを開発するのに必要なものが既にある程度整った状態で
スタートできるVue.jsベースのJavaScriptフレームワークです。
UIではVue.jsを使いますが、UI以外の機能についてもいろいろ組み込まれているようです。
フレームワークなので効率的にアプリケーションの開発ができるようですね。
Nuxt.jsのインストール
早速、自分のPCにインストールしてみます。
事前にnpm と Node.jsがインストールされていることが前提です。
npx create-nuxt-app プロジェクト名
この形式でインストールするようなので、
npx create-nuxt-app prj
プロジェクト名をprjとして実行してみました。
いくつか聞かれるので、
- server framework を Express
- Nuxt.js module をAxios
- rendering mode をUniversal (SSR)
として設定しました。
何度も繰り返し試した結果、上記の設定に落ち着きました。
Nuxt v2.10.2 がインストールされたようです。
次に、アプリを起動する必要があるので、
npm run dev
npm run スクリプト名
ここで、上記の形式で入力すると、package.json(下記)で記述されているscripts内のスクリプト名
(この場合は"dev")で定義されたコマンドが実行されます。
{
"name": "prj",
"version": "1.0.0",
"description": "My swell Nuxt.js project",
"author": "**** ****",
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development nodemon server/index.js --watch server",
"build": "nuxt build",
"start": "cross-env NODE_ENV=production node server/index.js",
"generate": "nuxt generate"
},
"dependencies": {
"@nuxtjs/axios": "^5.3.6",
"cross-env": "^5.2.0",
"express": "^4.16.4",
"fs": "0.0.1-security",
"mysql": "^2.17.1",
"net": "^1.0.2",
"nuxt": "^2.0.0",
"tls": "0.0.1"
},
"devDependencies": {
"nodemon": "^1.18.9"
}
}
下記URLをブラウザで表示すると、
http://localhost:3000
こんな感じに初期表示されました。
Nuxt.jsのデフォルトポートは3000のようです。
インストールされたあとのディレクトリ構造は下記のようになってました。
prj----assets
|--components
|--layouts
|--middleware
|--node_modules
|--pages
|--plugins
|--server
|--static
|--store
|nuxt.config.js
|package.json
調べたところ、最初に表示されたページは、
prj--
|--pages
|index.vue
pagesディレクトリ内にあるindex.vueに記載された内容でした。
<template>
<div class="container">
<div>
<logo />
<h1 class="title">
prj
</h1>
<h2 class="subtitle">
My laudable Nuxt.js project
</h2>
<div class="links">
<a
href="https://nuxtjs.org/"
target="_blank"
class="button--green"
>
Documentation
</a>
<a
href="https://github.com/nuxt/nuxt.js"
target="_blank"
class="button--grey"
>
GitHub
</a>
</div>
</div>
</div>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo
}
}
</script>
<style>
.container {
margin: 0 auto;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.title {
font-family: 'Quicksand', 'Source Sans Pro', -apple-system, BlinkMacSystemFont,
'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
display: block;
font-weight: 300;
font-size: 100px;
color: #35495e;
letter-spacing: 1px;
}
.subtitle {
font-weight: 300;
font-size: 42px;
color: #526488;
word-spacing: 5px;
padding-bottom: 15px;
}
.links {
padding-top: 15px;
}
</style>
ごちゃごちゃ書かれているので、余計な記述をバッサリ削除してコードを見やすくします。
<template>
<div class="container">
あいうえお
</div>
</template>
<script>
</script>
<style>
.container {
margin: 0 auto;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
表示は、下記のようになりました。
ここで気づいたのが、このindex.vueファイルを更新した場合、
ブラウザで再描画しなくても(F5押さなくても)自動でブラウザに反映されることです。
index.vueファイルを更新するたびに、自動でコンパイルが走るようで、
それが終わり次第ブラウザの表示が変更されるようです。
データベース準備
mysqlと連携させて何かしたいな?と考えたところ、
一番簡単なお試し内容として、DBに登録されているデータを取り出して、
それをブラウザに表示させてみるのがよさそうかなと思い、それを実装
してみることにしました。
なので、まずデータベースの準備をします。ローカル環境のmysqlにテスト用のデータベースを作成し
その中に都道府県情報のテーブルを作成しました。
データベース名:testdb
テーブル名:prefectures
この情報を取り出してブラウザに表示させてみようと思います。
必要なモジュール
mysqlを使うには、どうやらmysql用のモジュールをインストールする必要が
あることがわかりましたので下記を実行します。
npm install --save mysql
APIの実装
index.vueの中のscritpt要素の中に、データベースアクセスの為の記述をしても
うまくいかずエラーを解消することができなかったので、
別途APIを作成し、そこにアクセスすることでDBの内容をとってくる、
という方法にしました。
prj--
|--server
|api.js
serverディレクトの直下にapi.jsというファイルを作成し、
dbに接続してデータを取ってくるコードを記述します。
const express = require('express')
const router = express.Router()
router.get('/prefectures', (req, res, next) => {
const mysql = require('mysql');
const connection = mysql.createConnection({
host : 'localhost',
user : 'testuser',
database: 'testdb',
password: 'testuser'
});
var ret=[];
connection.connect();
connection.query('SELECT * from prefectures;', function(error, row, fields){
if (error) {
console.log(error);
}
var dat = [];
for (var i = 0;i < row.length; i++) {
dat.push({id: row[i].id, name: row[i].name});
}
ret = JSON.stringify(dat);
res.header('Content-Type', 'application/json; charset=utf-8')
res.send(ret)
});
connection.end();
})
module.exports = router
実はこれだけではだめなようで、同じディレクトリに存在するindex.jsというファイルを
一部編集しないといけないようです(★印の箇所)
const express = require('express')
const consola = require('consola')
const { Nuxt, Builder } = require('nuxt')
const app = express()
// Import and Set Nuxt.js options
const config = require('../nuxt.config.js')
config.dev = process.env.NODE_ENV !== 'production'
//↓↓↓★この行の追加
const apiRouter = require('./api')
async function start () {
//↓↓↓★この行の追加
app.use('/api', apiRouter)
// Init Nuxt.js
const nuxt = new Nuxt(config)
const { host, port } = nuxt.options.server
// Build only in dev mode
if (config.dev) {
const builder = new Builder(nuxt)
await builder.build()
} else {
await nuxt.ready()
}
// Give nuxt middleware to express
app.use(nuxt.render)
// Listen the server
app.listen(port, host)
consola.ready({
message: `Server listening on http://${host}:${port}`,
badge: true
})
}
start()
下記でアクセスするとDBからのデータをJSON形式でとってこれるようになりました。
http://localhost:3000/api/prefectures
参考サイト
https://dev.classmethod.jp/etc/node-js-module-mysq/
(他にもいくつか参考サイトがあったのですが忘れてしまった。。)
フロントエンドの実装
axiosというライブラリを使ってhttp通信を行います。
Node.jsで動作するhttpクライアントであり、通信するためのAPIが提供されているので
これを利用します(Ajaxのようなものですね。多分)
上記でばっさり削除したindex.vueの中を下記のように変更します。
先ほどのAPIにアクセスして取ってきたデータをitemsの中に格納すると、
Vue.jsによってフロントエンドに反映されます。
<template>
<div class="container">
<table border="1">
<tbody>
<tr>
<th>ID</th>
<th>都道府県名</th>
</tr>
<tr v-for="item in items" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
export default {
data() {
return {
items: []
}
},
mounted: function() {
this.$axios
.$get('/api/prefectures')
.then(response => {
this.items = response
})
.catch(error => {
console.log(error)
})
}
}
</script>
<style>
.container {
margin: 0 auto;
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
</style>
結果
表示は、下記のようになりました。
おわりに
今回は、mysqlとの連携に注目しましたが、Nuxt.jsに関する知識が浅いこともあり、
もっといろんなこともできると思われますので、今後も引き続きいろいろ試してみたいと思います。
私はPHPを使っての作業が多いので、JavaScriptだけで当たり前のようにWebアプリケーションを
作れるようなったことに関心を寄せています。
試した内容は大したものではないですが、それでも途中いくつもの壁にぶち当たりました。
が、なんとか乗り越えました。
今後はよりスムーズに実装できるよう一層進化していくことと思います。