4時に寝て7時に起きた。日曜日にたくさん寝たせいか、昨日は眠れなかった。サービスインの運用対応はまだまだドタバタしていてデータの不整合に苦しんでいるみたい。大変そうだけど、なにもやることない。

vuetify の v-data-table のページング処理

昨日から vuetify のページング処理を調査している。コンポーネント的には2種類ある。

  • v-pagination: 汎用のページングコンポーネント
  • v-data-table: data table のコンポーネント (ページング機能がある)

既存のアプリケーションは nuxtjs で実装されているので vuetify や vue.js のサンプルコードをそのまま動かせるわけではない。丸1日、試行錯誤していてビューと値の束縛、イベントの伝搬などの振る舞いをだいたい理解できた。宣言的なフレームワークなので振る舞いを理解できれば開発量は少なく済む。但し、理解するまで振る舞いを理解するのに設定を試行錯誤で試して動かすのでデバッグは時間がかかる。一覧画面で使っている v-data-table のページング処理対応から始める。Server-side paginate and sort を参考にしながら v-data-table に加えた主な変更はこれら。

<v-data-table
  ...
  :server-items-length="serverItemsLength"
  :disable-pagination="disablePagination"
  :hide-default-footer="hideDefaultFooter"
  :options.sync="options"
  :footer-props="{
    itemsPerPageOptions: [10, 20, 50, 100],
  }"
  v-bind="$attrs"
  v-on="$listeners"
>

v-data-table をラップするコンポーネントでは次のようにイベントリスナーを登録する。

<my-nice-component
  ...
 :server-items-length="serverItemsLength"
 :disable-pagination="false"
 :hide-default-footer="false"
  @update:options="dataOptionsHandler"
>

  async dataOptionsHandler(options: DataOptions) {
    const page = options.page ?? 1;
    const limit = options.itemsPerPage;
    const offset = limit * (page - 1);
    // limit/offset を使った web api リクエスト
  }

vm.$listeners によると v-on="$listeners" のように書くと、ラップしているコンポーネントのイベントリスナーをよしなに伝搬してくれるみたい。これはこれで便利だけど、イベントリスナーの定義がどこにもでてこないのでコード検索ができなくなる。最近の宣言的なフレームワークの流行りと言えばそうだけど、知ってないとなんで動くのかわからないコードにはなる。