6
6

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.

vuecliとphpを使ってHandsontableで読み込みと更新を作る

Last updated at Posted at 2018-02-05

概要

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をつけておきます。

index.html
<!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で外からデータを受け取れるようにしています。

SampleTable.vue
<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で遅延データ取得を実装。
データ取得後にshowtrueにすることでテーブルを表示するようにしています。
登録ボタンも一旦はalertのみ。

main.js
// 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

HotTable.vue
// 27行目の先頭の ~ をはずす。
@import "handsontable/dist/handsontable.full.css";

確認

実行

npm run dev

http://localhost:8080/
スクリーンショット 2018-02-05 18.06.58.png

表示できました。

スクリーンショット 2018-02-05 19.50.51.png

登録ボタンの動作もOK!

サーバー側作成とつなぎ込み

phpビルトインサーバーで簡単なjson取得と更新のAPIを作ります。

前提

php5.4↑が利用できる状態。

実装

今回はmy-project内にフォルダを作成します。

mkdir server
cd server

json

データ用のserver/tableData.jsonを作成します。

tableData.json
[{"name":"apple","price":100},{"name":"orange","price":120}]

php

読み込み、書き込み用のserver/tableData.phpを作成します。
POST時はファイルを更新します。

tableData.php
<?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を修正。
createdregisterをサーバーとのやり取りに修正します。

main.js
  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

確認

以下の状態で更新ボタンを押すと・・・
スクリーンショット 2018-02-05 20.36.30.png

しっかりファイルが更新されていました!
スクリーンショット 2018-02-05 20.37.10.png

まとめ

vuecliphpビルトインサーバーを利用することでかなりサクっと実装できました。
データも配列でやり取りできるのでシンプルに読み込みと更新を作れるのも良いです。

ただ、このままだとフロントコードをビルドしつつサーバー側との疎通確認ができません。
(vuecliで実行したサーバーとphpサーバーでクロスドメイン制約にひっかかる。
ので、もっとちゃんとやるならビルドされたコードを毎回サーバー側に配置するように設定変更する必要があります。

サンプルソースはこちら

6
6
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
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?