Web上でExcel風のテーブルを実装するHandsontableを使う-1
By: Tatsuya Asami
Tags: Handsontable, Vuejs, Excel, Vue Cli, Axios

APIデータをテーブルに読み込む。

今はHandsontable.vueのdataに初期テーブルデータをベタ書きしているが、実際にこのような使い方をすることはまれでしょう。APIデータを読み込む。ここが最初のつまずきポイント。

TableIndex.vueでApiデータを取得。

TableIndex.vue <template>

<Handsontable :members="members" :department="department" @getTableContents="getTableContents"/>

</template> <script>

import api from "axios";

import Handsontable from "./Handsontable";

name: "TableIndex",

components: {

Handsontable

},

data: function() {

return {

members: [],

department: []

};

},

computed: {

getUrl: () => "

},

methods: {

getMembers: function() {

return api.get(`${this.getUrl}/members`);

},

getDepartment: function() {

return api.get(`${this.getUrl}/department`);

},

getTableContents: async function() {

const getData = await api.all([this.getMembers(), this.getDepartment()]);

const membersData = getData[0].data;

const departmentData = getData[1].data; export default {name: "TableIndex",components: {Handsontable},data: function() {return {members: [],department: []};},computed: {getUrl: () => " http://localhost:3000 },methods: {getMembers: function() {return api.get(`${this.getUrl}/members`);},getDepartment: function() {return api.get(`${this.getUrl}/department`);},getTableContents: async function() {const getData = await api.all([this.getMembers(), this.getDepartment()]);const membersData = getData[0].data;const departmentData = getData[1].data; this.members = membersData;

this.department = departmentData;

}

}

};

</script> <style></style>

apiからmembersとdepartmentを取得し、dataに代入する関数をmethodsで記述している。

子コンポーネントのcreatedでその関数が実行される。

membersを表に反映させたい。Handsontable.vueで代入する。

Handsontable.vue <template>

<HotTable :data="members" :settings="hotSettings"/>

</template>

import { HotTable } from " import { HotTable } from " <a href="http://twitter.com/handsontable/vue" class="dy jm" rel="noopener ugc nofollow">@handsontable/vue</a> "; export default {

name: "Handsontable",

components: {

HotTable

},

props: {

members: {

type: Array,

default: []

},

department: {

type: Array,

default: []

}

},

data: function() {

return {

hotSettings: {

colHeaders: true,

rowHeaders: true

}

};

},

created: async function(） {

await this.$emit("getTableContents"); };

</script> <style src="../../node_modules/handsontable/dist/handsontable.full.css"></style>

はい、うまくレンダリングされません。リロードしてもダメです。しかし、どこか編集してセーブし、hot reloadが発生するとうまく読み込めます。

これはおそらくapiを取得する前にhandsontableがレンダリングされてしまうために発生する現象だと思われる。これがhandsontableの難しさである。

コレクションの場合は下記のようにcolumnsを指定するとうまく表示される。このようにちょっとした設定違いでうまくいかない部分があるので、場合によって長時間ハマってしまうが、試行錯誤すると大抵乗り越えられる。（ましてや今回はHot reloadだとうまく読み込めるので、試行錯誤の方向性をミスりやすい。）

// Handsontable.vue <template>

<div>

<HotTable :data="members" :settings="hotSettings"/>

</div>

</template>

import { HotTable } from " import { HotTable } from " <a href="http://twitter.com/handsontable/vue" class="dy jm" rel="noopener ugc nofollow">@handsontable/vue</a> "; export default {

name: "Handsontable",

components: {

HotTable

},

props: {

members: {

type: Array,

default: []

},

department: {

type: Array,

default: []

}

},

data: function() {

return {

hotSettings: {

colHeaders: true,

rowHeaders: true,

columns: [

{ data: "id", type: "text", placeholder: "ID" },

{ data: "name", type: "text", placeholder: "name" },

{ data: "mail", type: "text", placeholder: "mail" },

{ data: "department", type: "text", placeholder: "department" },

{ data: "position", type: "text", placeholder: "position" }

]

}

};

},

created: async function() {

await this.$emit("getTableContents");

},

methods: {

getTableData: function() {

this.$refs.hotTable.hotInstance.render();

console.log(this.$refs.hotTable.hotInstance.getData());

}

}

};

</script> <style src="../../node_modules/handsontable/dist/handsontable.full.css"></style>

これでapiデータが画面に反映される

Web上でExcel風のテーブルを実装するHandsontableを使う-2 に続く。

【わからなかったこと】

今はなし。

【感想】

ペースト機能、行の追加削除機能、バルクインポートを行わなければそこまで難しくない。次回以降厄介な部分の回避方法を紹介。