概要
Handsontableのvuejs用コンポーネントを利用して、サーバーからjsonファイルの読み込み
更新したデータでjsonファイルの更新を作ります。
Handsontableとは
WEB上でExcelのような機能を提供するjsライブラリのHandsontable。
配列でデータを表現できるので便利
フロントの表示まで作成
前提
公式Vue-Cliを導入して
http://localhost:8080/ が確認できる状態であること
インストール
cd my-project
npm install vue-handsontable-official
npm install handsontable
npm install babel-preset-es2015
npm install jquery
実装
html
cliでデフォルトで用意されているindex.html
に追加します。
json読み込みが終わってから表示したいのでv-if
をつけておきます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<title>Sample</title>
</head>
<body>
<div id="app">
<!-- 追加 -->
<sample-table v-if="show" :data="tableData"></sample-table>
<button @click="register">更新</button>
</div>
</body>
</html>
vue
src/components/SampleTable.vue
を新規作成。
vue-handsontable-officialこちらを参考に手を加えており、props
で外からデータを受け取れるようにしています。
<template>
<div id="example-container" class="wrapper">
<HotTable :root="root" :settings="hotSettings"></HotTable>
</div>
</template>
<script>
import HotTable from 'vue-handsontable-official';
import Vue from 'vue';
export default {
data: function () {
return {
root: 'test-hot',
hotSettings: {
colHeaders: ['name', 'price'],
rowHeaders: true,
data: this.data
},
}
},
name: 'SampleApp',
components: {
HotTable
},
props: ['data'],
}
</script>
<style>
#test-hot {
width: 600px;
height: 400px;
overflow: hidden;
}
</style>
js
main.jsを修正。
サーバーからのjson読み込みを想定して一旦setTimeout
で遅延データ取得を実装。
データ取得後にshow
をtrue
にすることでテーブルを表示するようにしています。
登録ボタンも一旦はalert
のみ。
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'
// 追加
import SampleTable from './components/SampleTable.vue'
Vue.component('sample-table', SampleTable);
Vue.config.productionTip = false
// 以下書き換え
new Vue({
el: '#app',
data: {
tableData: null,
show: false
},
created() {
setTimeout(() => {
this.tableData = [{"name":"apple","price":200},{"name":"orange","price":120}];
this.show = true;
}, 1000);
},
methods: {
register() {
alert(JSON.stringify(this.tableData) + '登録しました!');
}
},
});
ビルドが失敗する問題を修正
npm run dev
時に以下のエラーが発生。
ERROR Failed to compile with 1 errors 17:09:44
error in ./node_modules/vue-handsontable-official/src/HotTable.vue
Module build failed: Error: Failed to find '~handsontable/dist/handsontable.full.css'
https://github.com/handsontable/vue-handsontable-official/issues/23
ここを見て以下実装で一旦回避。node_modules
の中を修正しているのでイケてないですが・・
./node_modules/vue-handsontable-official/src/HotTable.vue
// 27行目の先頭の ~ をはずす。
@import "handsontable/dist/handsontable.full.css";
確認
実行
npm run dev
表示できました。
登録ボタンの動作もOK!
サーバー側作成とつなぎ込み
phpビルトインサーバーで簡単なjson取得と更新のAPIを作ります。
前提
php5.4↑が利用できる状態。
実装
今回はmy-project
内にフォルダを作成します。
mkdir server
cd server
json
データ用のserver/tableData.json
を作成します。
[{"name":"apple","price":100},{"name":"orange","price":120}]
php
読み込み、書き込み用のserver/tableData.php
を作成します。
POST時はファイルを更新します。
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$file = new SplFileObject('tableData.json', 'w');
$file->fwrite(json_encode($_POST['data']));
} else {
$file = new SplFileObject('tableData.json');
echo $file->fgets();
}
js
src/main.js
を修正。
created
とregister
をサーバーとのやり取りに修正します。
created() {
$.getJSON('tableData.php', (data) => {
this.tableData = data;
this.show = true;
});
},
methods: {
register() {
$.ajax({
type: 'POST',
url: 'tableData.php',
data: {data: this.tableData}
}).then(function () {
alert('登録しました!');
});
}
},
フロントコードビルド
php側のサーバーで実行するためフロントコードのビルドを行って静的ファイルを作成。
サーバー側のフォルダへ移動させます。
my-project
配下で実行します。`
cd my-project
npm run build
dist
フォルダ配下にビルドされたコードがあるので、server
フォルダへ移動します。
mv dist/* server
サーバー実行
php -S localhost:3330
確認
まとめ
vuecli
とphpビルトインサーバー
を利用することでかなりサクっと実装できました。
データも配列でやり取りできるのでシンプルに読み込みと更新を作れるのも良いです。
ただ、このままだとフロントコードをビルドしつつサーバー側との疎通確認ができません。
(vuecliで実行したサーバーとphpサーバーでクロスドメイン制約にひっかかる。
ので、もっとちゃんとやるならビルドされたコードを毎回サーバー側に配置するように設定変更する必要があります。
サンプルソースはこちら。