Vuetify 3でページングを実装する

公式HPにある以下を使用して、実装していきます。

 

vuetifyjs.com

 

Vuetify 3を使用できる状態であることが前提とします。

まだできていない方は以下を参考にしてプロジェクトを作成してみてください。

challenge-think.hatenablog.com

 

まず、以下をページネーションを作成したい場所にコピペします。


    h1>タイトル</h1>
    <v-table density="conpact">
      <thead>
        <tr>
          <th width=10px class="text-left">
            <div  class="d-flex flex-wrap flex-row">
              Date
              <div style="margin: 0% 0% 0% 10%; color: gray;">
                <v-chip
                  density="compact"
                  @click="changeOrder()"
                  v-bind:text="orderType"
                ></v-chip>
              </div>
            </div>
          </th>
          <th class="text-left">
            Title
          </th>
        </tr>
      </thead>
      <tbody>
        <tr
          v-for="newsInfo in pageList[page-1]"
          :key="newsInfo.title"
        >
          <td>{{ newsInfo.date }}</td>
          <td v-html="newsInfo.title"></td>
        </tr>
      </tbody>
    </v-table>
    <div class="text-center">
      <v-pagination
        v-model="page"
        v-bind:length="totalPages"
        :total-visible="6"
        density=conpact
      ></v-pagination>
    </div>

次に、同じ.vueファイルのscriptに以下をコピペします。


    import { ref, computed, reactive} from 'vue'; 
  import NewsInfoList_RAW from '@/assets/data/NewsData';
  
  const page = ref(1);

  /* ブログをソートする */
  const daySort = (a,b) => {
    const [ a_year, a_month, a_day ] = a.date.split('.');
    const [ b_year, b_month, b_day ] = b.date.split('.');

    if(a_year !== b_year){
      return a_year - b_year;
    }else if(a_month !== b_month){
      return a_month - b_month;
    }else if(a_day !== b_day){
      return a_day - b_day;
    }
  }
  var NewsInfoList = NewsInfoList_RAW.sort((a,b) => daySort(b, a));
  const orderType = ref("↓");

  // 1ページあたりの記事数
  const parPage = 10;

  /* 総ページ数を数える */
  var syou = (NewsInfoList.length)/parPage;
  var totalPages;
  if(syou%1 === 0){
    totalPages = Math.floor(syou);
  }else{
    totalPages = Math.floor(syou)+1;
  }

  var pageList = reactive([]);
  var newsCount;
  /* ページごとにブログを分割する */
  const createPageList = (NewsInfoList) => {
    pageList.splice(0); // 配列を空にする
    newsCount = 0;
    for(let i=0; i<totalPages; i++){
      pageList[i]=[];
      for(let j=0;j<parPage;j++){
        if(newsCount<NewsInfoList.length){
          pageList[i][j] = NewsInfoList[newsCount++];
        }
      }
    }
  }
  /* ページ毎にブログを格納する */
  createPageList(NewsInfoList);

  /* 昇順・降順変更 */
  const changeOrder = () => {
    if(orderType.value === "↑"){
      orderType.value = "↓";
      NewsInfoList = NewsInfoList_RAW.sort((a,b) => daySort(b, a));
    }else{
      orderType.value = "↑";
      NewsInfoList = NewsInfoList_RAW.sort((a,b) => daySort(a, b));
    }
    /* ページ毎にブログを格納する */
    createPageList(NewsInfoList);
  }

最後にimportしてくる元々のデータを作成します。 新しく.jsファイルを作成し、以下をコピペしてください。 ※上記のscriptの部分でimportしているので、パスを正確に書き換えてください。


    const NewsInfoList_RAW = [
  {
    type : "hoby", 
    date : "2023.04.09",
    title: `<a href="https://challenge-think.hatenablog.com/" target="_blank">Webサイト</a>をリニューアルしました`,
  },
]

export default NewsInfoList_RAW;

ただ、ここで、export defaultは余り推奨されないようです。

engineering.linecorp.com