来週辺りから、盆休みですが、コロナ禍蔓延中でもあり、猛暑でもあり
ずっと家にいるのかなと思います。リモートワーク中なので、今もそうですが、ずっと椅子の上、姿勢は同じ。
休日は、ただ仕事してないだけです。
で、何かないかと・・・、ああそうだ・・・折角、憶えたNuxtjsを忘れてしまわないようにと・・・
(ボーっとしてにいると無価値存在と自己を責めてしまいがち・・・困った性癖です!)
HTAで作成した、HTA/MySQL版 テーブル一覧を、Nuxt.js で作成してみました。
登録されているテーブルを、画面の作り込みなしで、参照・表示します。
難点は、項目の表示幅が、アジャスト出来ていないことと、
javascript なので日付が、時刻まで表示されてしまうこと(グリニッジ標準時で)
HTA版は、更新機能を追加しましたが、こっちは考えていません。
(プライマリーキーの扱いが難しいので、oracleならROWIDを使うんですが・・・)
【前提】
・windows
・node.js, npm はインストール済
【バックエンド】 仮にホームディレクトリは、「api-nuxt-mytable」とする。<== 任意です。
・ターミナル(コマンドプロンプト、管理者で起動)
$ mkdir api-nuxt-mytable <== 仮(任意です、お好きに)
$ cd api-nuxt-mytable <== 仮
$ npm init
$ npm install express
$ npm install mysql
$ mkdir api
$ cd api
■/api/index.js を作成
const express = require('express'); // expressを利用することを定義
const app = express(); // expressをappと定義
const mysql = require('mysql'); // MySQLを利用する
const connection = mysql.createConnection({ // 以下、各自のMySQLへの接続情報を書く
host : 'localhost',
user : '(MySQLの接続ユーザー)', // 環境に合わせて変更する
password : '(〃の接続パスワード)', // 同上
database : '(〃のデータベース名)' // 同上
});
app.get('/', function (req, res) { // app.get...(expressの構文)、req=request。 res=response
res.set({ 'Access-Control-Allow-Origin': '*' }); // この記載により、※1:CORSを許可する
connection.query('SELECT TABLE_NAME,TABLE_COMMENT,TABLE_ROWS,CREATE_TIME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = "(スキーマ名)"', function (error, results) {
if (error) throw error; // エラー処理
res.send(results);
});
});
app.get('/recList', function (req, res) { // app.get...(expressの構文)、req=request。 res=response
const tbl = req.query.tbl;
console.log('TABLE ID' + tbl);
const sql = 'SELECT C.COLUMN_COMMENT AS text,C.COLUMN_NAME AS value,' +
' CASE WHEN C.CHARACTER_MAXIMUM_LENGTH IS NULL THEN 100' +
' WHEN C.CHARACTER_MAXIMUM_LENGTH > 100 THEN 500' +
' WHEN C.CHARACTER_MAXIMUM_LENGTH < 13 THEN 100' +
' ELSE C.CHARACTER_MAXIMUM_LENGTH * 8 END AS width' +
' FROM information_schema.COLUMNS C' +
' WHERE C.TABLE_SCHEMA = "(スキーマ名)" AND C.TABLE_NAME = ?';
res.set({ 'Access-Control-Allow-Origin': '*' }); // この記載により、※1:CORSを許可する
connection.query(sql, tbl, function (error, results) { // テーブルカラムを取得する
if (error) throw error; // エラー処理
res.send(results);
});
});
app.get('/search', function (req, res) { // app.get...(expressの構文)、req=request。 res=response
const tbl = req.query.tbl;
console.log('TABLE ID' + tbl);
const sql = 'SELECT * FROM ' + tbl;
res.set({ 'Access-Control-Allow-Origin': '*' }); // この記載により、※1:CORSを許可する
connection.query(sql, function (error, results) { // テーブルデータを取得する
if (error) throw error; // エラー処理
res.send(results);
});
});
app.listen(5000, function () { // port 5000をlistenする
console.log('Example app listening on port 5000!'); // console.logによりファイル実行時にコンソールに文字表示させる
});
・ターミナル(コマンドプロンプト)…server起動(停止はCTRL + C)
$ node index.js
【フロントエンド】ホームディレクトリは、今回は「nuxt-mytable-app」とします。<== 任意です。
・ターミナル(コマンドプロンプト、管理者で起動)
$ npx create-nuxt-app nuxt-mytable-app <== ※プロジェクト名は任意
※選択肢は、ほとんど規定値かNone 但し、UI framework: Vuetify.js だけは意識して選択
create-nuxt-app v4.0.0
✨ Generating Nuxt.js project in nuxt-mytable-app
? Project name: nuxt-mytable-app
? Programming language: JavaScript
? Package manager: Npm
? UI framework: Vuetify.js
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: ESLint
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: (Press to select, <a> to toggle all, <i> to invert selection)
? Continuous integration: None
? Version control system: Git
🎉 Successfully created project nuxt-mytable-app
To get started:
cd nuxt-mytable-app
npm run dev
To build & start for production:
cd nuxt-mytable-app
npm run build
npm run start
・上記案内に従って、起動確認(修正前に一旦確認)
$ cd nuxt-mytable-app <== ※プロジェクト名(今回)
$ npm run dev
・ブラウザで表示
http://localhost:3000
今回は、vue-json-to-csvという機能を追加します。
$ npm i vue-json-to-csv
さあ、ここから修正です。
■../pages/tableList.vue を作成し追加します。
※↓以下 半角の< と > は、全角の < と > に置換して掲載しています。
--------------------------------------------------
<template>
<dev>
<v-row>
<v-col>
<v-card-title>
TABLELIST
<v-spacer />
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
/>
</v-card-title>
</v-col>
<v-col>
<v-card-actions>
<v-btn
class="primary"
@click="downloadData()"
>
CSV
</v-btn>
</v-card-actions>
</v-col>
</v-row>
<v-data-table
:headers="headers"
:items="lists"
:search="search"
item-key="line"
>
<template #[`item.TABLE_NAME`]="{ item }">
<a :href="`http://localhost:3000/recList?tbl=${item.TABLE_NAME}`">
{{ item.TABLE_NAME }}
</a>
</template>
<template #[`item.CREATE_TIME`]="{ item }">
{{ item.CREATE_TIME.slice(0,10) }}
</template>
</v-data-table>
</dev>
</template>
<script>
/* eslint-disable no-console */
export default {
name: 'TableList',
async asyncData ({ $axios }) {
try {
const lists = await $axios.$get('http://localhost:5000')
return { lists }
} catch (e) {
console.log(e.errorCode) // eslint-disable-line no-console
window.alert(e)
}
},
data () {
return {
search: '',
headers: [
{
text: 'テーブルID',
value: 'TABLE_NAME'
},
{
text: 'テーブル名',
value: 'TABLE_COMMENT'
},
{
text: '件数',
value: 'TABLE_ROWS'
},
{
text: '作成日',
value: 'CREATE_TIME'
}
],
lists: []
}
},
methods: {
downloadData () {
let csv = 'テーブルID,テーブル名,件数,作成日\n'
this.lists.forEach(function (el) {
csv += el.TABLE_NAME + ',' + el.TABLE_COMMENT + ',' + el.TABLE_ROWS + ',' + el.CREATE_TIME + '\n'
})
const anchor = document.createElement('a')
anchor.href = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv)
anchor.target = '_blank'
anchor.download = 'TABLE_LIST_' + new Date().toISOString().substr(0, 10) + '.csv'
anchor.click()
}
}
}
</script>
<style>
.v-data-table th {
background: #8C9EFF;
}
.v-data-table td {
background: #e0e0e0;
}
.v-data-table tr:nth-child(odd) td {
background: #f5f5f5;
}
.v-data-table tr:hover td {
background-color: #eee;
}
</style>
--------------------------------------------------
■../pages/recList.vue を作成し追加します。
※↓以下 半角の< と > は、全角の < と > に置換して掲載しています。
--------------------------------------------------
<template>
<dev>
<v-row>
<v-col>
<v-card-title>
{{ tblId }}
<v-spacer />
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
/>
</v-card-title>
</v-col>
<v-col>
<v-card-actions>
<VueJsonToCsv
:json-data="lists"
:csv-title="csvFile"
>
<v-btn
class="primary"
>
CSV
</v-btn>
</VueJsonToCsv>
<v-btn
class="primary"
@click="home()"
>
戻る
</v-btn>
</v-card-actions>
</v-col>
</v-row>
<v-data-table
:headers="headers"
:items="lists"
:search="search"
item-key="line"
/>
</dev>
</template>
<script>
/* eslint-disable no-console */
export default {
data () {
return {
tblId: this.$route.query.tbl,
search: '',
headers: [],
lists: [],
json_meta: [
[{
key: 'charset',
value: 'utf-8'
}]
],
inTblId: this.$route.query.tbl,
csvFile: this.$route.query.tbl + '_' + new Date().toISOString().substr(0, 10)
}
},
created () {
this.searchDate()
},
methods: {
async searchDate () {
if (!this.inTblId) {
window.alert('検索キーが未設定です!')
return
}
try {
const res = await this.$axios.$get('http://localhost:5000/recList', {
params: {
tbl: this.inTblId
}
})
this.headers = res
} catch (e) {
console.log(e.errorCode) // eslint-disable-line no-console
window.alert(e)
}
try {
const res = await this.$axios.$get('http://localhost:5000/search', {
params: {
tbl: this.inTblId
}
})
this.lists = res
} catch (e) {
console.log(e.errorCode) // eslint-disable-line no-console
window.alert(e)
}
},
home () {
this.$router.push('/tableList')
}
}
}
</script>
<style>
.v-data-table th {
background: #8C9EFF;
}
.v-data-table td {
background: #e0e0e0;
}
.v-data-table tr:nth-child(odd) td {
background: #f5f5f5;
}
.v-data-table tr:hover td {
background-color: #eee;
}
</style>
--------------------------------------------------
■..\plugins\vue-json-to-csv.js を以下のように作成する。
--------------------------------------------------
import Vue from 'vue'
import VueJsonToCsv from 'vue-json-to-csv'
Vue.component('VueJsonToCsv', VueJsonToCsv)
--------------------------------------------------
■..\nuxt.config.js の plugins: と vuetify:のthema: 部分を以下のように修正する。
--------------------------------------------------
plugins: [
{ src: '@/plugins/vue-json-to-csv.js' }
],
vuetify: {
customVariables: ['~/assets/variables.scss'],
theme: {
light: true,
themes: {
light: {
background: '#d0f0c0',
primary: '#00ced1',
secondary: '#f08080',
accent: '#9370db',
error: '#2f4f4f'
}
}
}
},
--------------------------------------------------
【起動確認】
・バックエンド $ node index.js を実行した状態で
・フロントエンド
$ cd nuxt-mytable-app <== ※プロジェクト名(今回)
$ npm run dev
・ブラウザで表示
http://localhost:3000/tableList
ネット学習(として)の生半可、寄せ集め、理解せずに作成、掲載してます。
こうしたら、もっと簡単で、高機能だよいうのが分かる方(誇りたい方、決めたい方はご遠慮下さい)
ご教授ください。老齢初心者です。
■GITHUB
https://github.com/frontflg/MYTABLE_NUXTJS
最新の画像[もっと見る]
-
Re:SALLON BBSの倉庫として 5ヶ月前
-
「決め・分け論64」欲求の4タイプ 12ヶ月前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
-
Django で読書履歴管理システム(BOOKLOG) 1年前
は、見苦しいので、無理やり置換するという方法で対応しました。
以下を■../pages/recList.vue の this.lists = res の後に入れます。(無理やりです。)
for (const item in this.lists) {
for (const subItem in this.lists[item]) {
try {
const str = this.lists[item][subItem]
if (str !== null && str.indexOf('T15:00:00.000Z') > 0) {
const dt = new Date(Date.parse(str))
const month = ('0' + (dt.getMonth() + 1)).slice(-2)
const day = ('0' + dt.getDate()).slice(-2)
this.lists[item][subItem] = dt.getFullYear() + '-' + month + '-' + day
}
} catch (e) { } // 握りつぶす
}
}
$ npm install oracledb
■/api/index.js の設定部分
const oracledb = require('oracledb'); // 今回はoracleを利用する
const connection = oracledb.getConnection({ // 以下、各自のOracleへの接続情報を書く
user : '(接続ユーザーID)',
password : '(接続パスワード)',
connectString: 'localhost:1521/(スキーマ名)'
});
■/api/index.js のSQL部分①
connection.query('SELECT T.TABLE_NAME,C.COMMENTS,T.NUM_ROWS,LAST_ANALYZED FROM ALL_TABLES T LEFT JOIN USER_TAB_COMMENTS C ON T.TABLE_NAME = C.TABLE_NAME WHERE T.OWNER = "TESTUSER" ORDER BY T.OWNER,T.TABLE_NAME', function (error, results) {
■/api/index.js のSQL部分②
const sql = 'SELECT C.COMMENTS AS text,T.COLUMN_NAME AS value,' +
' CASE WHEN T.DATA_TYPE = "DATE" THEN 110' +
' WHEN T.DATA_TYPE = "NUMBER" THEN T.DATA_PRECISION * 4 + 50' +
' WHEN T.DATA_LENGTH IS NULL THEN 100' +
' WHEN T.DATA_LENGTH > 90 THEN 500' +
' WHEN T.DATA_LENGTH < 13 THEN 100' +
' ELSE T.DATA_LENGTH * 5 + 40 END AS width' +
' FROM ALL_TAB_COLUMNS T' +
' LEFT JOIN USER_COL_COMMENTS C' +
' ON T.TABLE_NAME = C.TABLE_NAME' +
' AND T.COLUMN_NAME = C.COLUMN_NAME' +
' WHERE T.TABLE_NAME = ? ORDER BY T.COLUMN_ID';