kintoneアプリの一覧画面をVue3+Vuetify3を使って表示
前回に引き続き、今度はVue3+Vuetify3を使ってkintoneの一覧画面を表示したいと思います。
Vuetify3のロードマップをみるとまだまだ開発中という感じですが、Vue2+Vuetify2もサポート終了なので、ああでもないこうでもないと試行錯誤しながらようやく出来上がりました。
こちらもぜひご利用ください!
1. 利用環境
以下の環境で動作しています。
- kintone … クラウド最新版(2025年1月時点)
- Vue2 … バージョン3.5.13
- Vuetify2 … バージョン3.7.7
2. 用意するもの
2-1. 一覧画面を作成
アプリ管理 → 一覧 → 「+」マーク から、新しい一覧をカスタマイズ形式で作成します。
本記事では以下のように設定します。
一覧名 | レコード一覧の表示形式 | 一覧を表示する範囲 | ページネーションを表示する |
---|---|---|---|
Vue3+Vuetify3一覧 | カスタマイズ | PC版のみで表示する | チェックオフ |
2-2. テストデータ
テストデータはこんな感じです。
3. スクリプト全体
一覧に設定するHTMLと、JavaScript/CSSカスタマイズに設置するスクリプトを記載します。
3-1. HTML
<div id="kintone-vue3-app">
<v-app>
<v-main>
<v-container fluid>
<v-row class="bg-deep-purple-lighten-5">
<v-col class="ma-2" cols="12">
<v-data-table
:headers="headers"
:items="userList"
:loading="isLoading"
></v-data-table>
</v-col>
</v-row>
</v-container>
</v-main>
</v-app>
</div>
さきほど作成した「Vue3+Vuetify3一覧」のHTMLフィールドに本内容をコピペ。
コンポーネントを識別しやすいように、
-
v-row
の属性にclass="bg-deep-purple-lighten-5"
を追加して背景色を薄紫色に -
v-col
の属性にclass="ma-2"
を追加してマージンを設定
と、Vue2+Vuetify2のときと同じ装飾を加えています。
記法に若干の違いがあるので記載しておくと、色の指定は以下のように変更になりました。
- <v-row class="deep-purple lighten-5">
+ <v-row class="bg-deep-purple-lighten-5">
3-2. JavaScript
次に「customizeView.js」という名称で以下の内容を保存します。
((Vue,Vuetify) => {
const events = {
show: [
'app.record.detail.show',
'mobile.app.record.detail.show',
],
index: [
'app.record.index.show',
'mobile.app.record.index.show',
]
}
let vObj = null;
async function getRecords(appId) {
const client = new KintoneRestAPIClient();
const params = {
app: appId,
}
return await client.record.getAllRecords(params).then((resp) => {
return resp.map((row) => {
row.hogehoge = 'テストデータですよー!'
return row
});
})
}
function generateView() {
const vObj = Vue.createApp({
data() {
const columnList = [
{
title: 'ユーザー名', //表示名
key: 'userName.value', //kintoneアプリのどの項目を表示するか
sortable: true, //列タイトルクリックしたときにソートできるかどうか
},
{title: 'ユーザーID', key: 'userID.value'},
{title: 'メールアドレス', key: 'mailAddress.value'},
{title: '生年月日', key: 'birthday.value'},
{title: 'ふがふが', key: 'hogehoge'},
]
const users = Vue.ref([]);
function addUser(value) {
users.value.push(value)
}
function addUsers(value) {
users.value = value
}
const loadingValue = Vue.ref(true);
function changeLoadingState(value) {
loadingValue.value = value
}
return {
columns: columnList,
userList: users,
addUser,
addUsers,
isLoading: loadingValue,
changeLoadingState,
}
},
}).use(
Vuetify.createVuetify({
icons: {
iconfont: 'mdi',
},
})
)
return vObj.mount('#kintone-vue3-app')
}
kintone.events.on(events.index, async function(event) {
if (event.viewType!=='custom' || event.viewId!==5536090) {return event;};
const appId = event.appId
vObj = generateView()
await getRecords(appId).then((resp) => {
vObj.addUsers(resp)
});
vObj.changeLoadingState(false);
return event;
});
})(Vue,Vuetify);
4. 説明
4-1. スクリプトを動作させる一覧画面を指定する
if (event.viewType!=='custom' || event.viewId!==5536090) {return event;};
アプリ内のいろんなページで動作してもらっては困るので、しょっぱなで一覧IDを指定しておきます。
この箇所にあるevent.viewId
は環境ごとにかわりますので、5536090
の箇所を、前段階で作成した一覧画面に記載の一覧IDに書き換えてください!
4-2. Vueオブジェクト生成時のポイント
data() {}
内に設定しているレコード一覧userList
等をref()
でラップして設定
data() {
const users = Vue.ref([]);
function addUser(value) {
users.value.push(value)
}
function addUsers(value) {
users.value = value
}
const loadingValue = Vue.ref(true);
function changeLoadingState(value) {
loadingValue.value = value
}
return {
columns: columnList,
userList: users,
addUser,
addUsers,
isLoading: loadingValue,
changeLoadingState,
}
},
<v-data-table>
のデータ本体としたいuserList
は初期段階で空配列としています。
対象データが大量な場合は表示までにレスポンスがなく、ユーザビリティが低下するのを防ぐ狙いがあります。
BooleanのisLoading
を用意してロード中という事を伝えているのも同じ理由です。
なお
userList
はHTML内の:items="userList"
と、
isLoading
はHTML内の:loading="isLoading"
と、
それぞれ関連付けています。
vue3ではcomposition API
という仕組みが使えるようになっていて、
const users = Vue.ref([]);
function addUser(value) {
users.value.push(value)
}
function addUsers(value) {
users.value = value
}
といった、"値"と、"それに対して行いたい処理" をまとめた記述ができというのが大きなメリットになっています。
vue2ではmethods
内やcomputed
内に分散させなければならなかったので助かります。
現在はパッと見で全容を把握・整理できる分量の開発しかしていないのでメリットを感じづらいですが、大規模な開発になるにつれこのメリットが活きてくるのではと思います。
タイトル行を設定
data() {
const columnList = [
{
title: 'ユーザー名', //表示名
key: 'userName.value', //kintoneアプリのどの項目を表示するか
sortable: true, //列タイトルクリックしたときにソートできるかどうか
},
{title: 'ユーザーID', key: 'userID.value'},
{title: 'メールアドレス', key: 'mailAddress.value'},
{title: '生年月日', key: 'birthday.value'},
{title: 'ふがふが', key: 'hogehoge'},
]
// ~
return {
columns: columnList,
}
}
columns
を用意し、<v-data-table>
のタイトル行として設定します。
HTML内の:headers="columns"
でこのオブジェクトと関連付けています。
なおVue2からの変化はこんな感じです↓
- {text: 'ユーザーID', value: 'userID.value'},
+ {title: 'ユーザーID', key: 'userID.value'},
表示名はtext
からtitle
に変更、内部値はvalue
からkey
に変更になっています。
key
に記述する内容は、kintoneのフィールドコード+「.value」といつも使っている形式で変更なし、getRecords()
した内容をそのまま使うわけではない場合は、最後の「ふがふが」列のようになります。
肝心のVuetifyを、プラグインとして使うよう設定
.use(
Vuetify.createVuetify({
icons: {
iconfont: 'mdi',
},
})
)
Vue2+Vuetify2のパターンから変化のあった箇所です。
Vue2ではVueオブジェクトの一データとして生成していましたが、Vue3ではuse()
を使ってプラグイン追加します。
前回と同様アイコンを使うときに備えてicons: {iconfont: 'mdi'}
を指定しています。
マウント
return vObj.mount('#kintone-vue3-app')
ここもVue2+Vuetify2のパターンから変化がありました。
微妙な違いですが、.$mount()
から.mount()
になっています。これでHTMLの指定idとの紐づけも完了!
↑ここまでの処理が一通り終わったら…
await getRecords(appId).then((resp) => {
vObj.addUsers(resp)
});
vObj.changeLoadingState(false);
最後にレコード取得&設定と、ローディングバー非表示して完了です。
それぞれsetup()
内で作成したaddUsers()
とchangeLoadingState()
を介して、リアクティブなオブジェクトの値を更新しています。
5. アプリにライブラリ等を反映
アプリ管理 → 設定 → カスタマイズ/サービス連携 → JavaScript/CSSでカスタマイズ
の中に、上から順に以下内容を追加します。
- PC用のJavaScriptファイル
- (URL指定) https://js.cybozu.com/vuejs/v3.5.13/vue.global.prod.js
- (URL指定) https://cdn.jsdelivr.net/npm/vuetify@3.7.7/dist/vuetify.min.js
- (URL指定) https://js.cybozu.com/kintone-rest-api-client/5.6.0/KintoneRestAPIClient.min.js
- (ファイル指定) 先ほど保存した「customizeView.js」
- PC用のCSSファイル
全て指定できたら「保存」→「アプリを更新」します。
6. 完成
ここまでのステップが終了すると、こんな感じになります↓
7. さいごに
Vue3+Vuetify3もこれでようやく、カスタマイズのための足掛かりができました!
Vue2+Vuetify2がサポート切れるのは残念ですが、これで何とか開発効率化につなげられたらなあと思う次第です。
Discussion