フロントエンドのページネーション効果

序文

        実際の開発では、ほとんどのページングは​​バックエンドで行われます。しかし、そうでない場合もあれば、そうでない場合もあります。バックエンドは一度にすべてのデータを返します。フロントエンドですべてのデータを表示することは不可能ですが、ページング効果を作成することはできません。There are also some scenario that require the front-end to create pagination, such as uploading an Excel table to display on the desired page. テーブル内のデータが十分な場合は、ページング効果も作成する必要があります。

        次に、配列内のメソッドを使用して、sliceVue でフロントエンドのページング効果を実現します。

原理

        フロントエンドのページネーションを実装することは難しくありません.配列を必要とするメソッドを使用してくださいslice.公式サイトでこのメソッドの紹介を見てください.slice()メソッドは、元の配列が決定された新しい配列オブジェクトを返します. by begin および end 浅いコピー (begin を含み、end を除く)。元の配列は変更されません。この文を読んだ後、このメソッドは元の配列を破棄せずに新しい配列を返すことがわかります。実際、データを切り取り、切り取った断片を返します。

        sliceメソッドは最大2 つのパラメーターを受け取ることができます。1つを渡すか、何も渡さないでください次の栗を使用して、このメソッドの使用法を理解してください。

使用 1: パラメータを渡さない

        明らかに、パラメーターを渡さない場合、配列全体が返されます。つまり、パラメーターが渡されない場合、元の配列はカットされません。

// 准备一个数组
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']

// slice 不传参数

const newSect = sect.slice()

console.log(newSect)
// (10) ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']

使用 2: パラメータを渡す

        明らかに、パラメーターを渡すと、カット配列が得られます。

  • 1を渡すと、インデックス 1 の要素から最後の要素までインターセプトされます。

  • 6を渡すと、インデックス 6 の要素から最後の要素までインターセプトされます。

  • 10を渡すと、インデックス 10 の要素から最後の要素までインターセプトされます。この配列の長さは 10 なので、最大インデックスは です9したがって、最初のパラメーターが配列インデックスより大きい場合、空の配列が返されますが、これも妥当です。

  • それを渡すと、インデックス 8 の要素からインターセプト-2されますが、なぜ 8 から開始するのでしょうか? パラメータが負の場合は、全員に式: を与えます。この例では: です彼が逆に数えたと言うこともできますが、それは何も悪いことではありません! (理解度最大)arr.length + 参数10 + (-2) = 8

つまり、パラメーターが渡されると、最初のパラメーターから最後の要素までのイ​​ンデックスがインターセプトされ、返されます。パラメータが最大インデックスよりも大きい場合、空の配列が返されます; パラメータが負の場合、インターセプトの開始位置が逆になります (わからない場合は、上記の式を使用できます)。

// 准备一个数组
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']

const newSect1 = sect.slice(1)
const newSect2 = sect.slice(6)
const newSect3 = sect.sect(10)
const newSect4 = sect.slice(-2)

console.log(newSect1)
// (9) ['武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']

console.log(newSect2)
// (4) ['古墓派', '全真教', '丐帮', '明教']

console.log(newSect3)
// []

console.log(newSect4)
// (2) ['丐帮', '明教']

使用 3: 2 つのパラメーターを渡す

        明らかに、2 つのパラメーターを渡すと、カット配列も得られますが、インターセプトは必ずしも最後の要素に到達するとは限りません。

  • 0 と 2を渡すとインデックス 0からインデックス 2 までの要素をインターセプトします(インデックス 2 の要素を除く)。

  • 8 と 20を渡すとインデックス 8からインデックス 20 までの要素をインターセプトします(インデックス 2 の要素を除く)。sectこの配列の最大インデックスは であるため9、インデックス 8 と 9 の要素のみをインターセプトします。2 番目のパラメーターが配列の最大インデックスより大きい場合、最後の要素がインターセプトされるとも言えます。

  • それを渡すと-2和-1インデックス 8からインデックス 9 までの要素をインターセプトします(インデックス 9 の要素を除く)。なぜ?ここでは、上記の式: も使用できます。arr.length + 参数この例では、最初のパラメーター: 10 + (-2) = 8、2 番目のパラメーター: であるため、 sect.slcie(8, 9)10 + (-1) = 9です

  • それを渡すと-2和-3、原則として、インデックス 8からインデックス 7 までの要素をインターセプトします(インデックス 7 の要素を除く)。从左往右このケースは特殊で、インターセプトがではないため、空の配列が返されます从右往左

つまり、2 つのパラメーターが渡されると、最初のパラメーターのインデックスから 2 番目のパラメーターのインデックスの最後まで (このインデックスを除く) をインターセプトし、それを返します。2 番目のパラメーターが最大インデックスよりも大きい場合、最後の要素が切り捨てられます。2 番目のパラメーターが最初のパラメーターより小さい場合、空の配列が返されます。パラメーターが負の場合は、反転されて位置のインターセプトが開始されます。 (わからない場合は、上記の式を使用できます)。

// 还是准备一个数组
const sect = ['少林派', '武当派', '逍遥派', '峨眉派', '华山派', '日月神教', '古墓派', '全真教', '丐帮', '明教']

const newSect1 = sect.slice(0, 2)
const newSect2 = sect.slice(8, 20)
const newSect3 = sect.slice(-2, -1)
const newSect4 = sect.slice(-2, -3)

console.log(newSect1)
// (2) ['少林派', '武当派']

console.log(newSect2)
// (2) ['丐帮', '明教']

console.log(newSect3)
// (1) ['丐帮']

console.log(newSect4)
// []

この方法に精通している場合は、上記の内容をスキップして、すぐ下を読むことができます。あなたがそれに精通しているなら、兄貴は間違いなくあなたにレッスンを与えると信じています!! !

達成

アイデア: vue のライフサイクル機能で、すべてのデータを要求し、配列に格納します。次に、配列をインターセプトするメソッドをカプセル化して、すべてのデータを格納する配列をインターセプトします。呼び出しごとに、ページング効果を実現する配列フラグメントが返されます。element-ui+を使用するチュートリアルは次のとおりですvue

        data では、合計データを受け入れる変数、実際にデータを表示する変数 (つまり、合計データ配列に格納されたセグメント)、およびページの合計数 (つまり、ファイルの長さ) を含む変数を定義します。合計データ) 、現在のページの変数 (デフォルトは最初のページ)、サイズのない変数 (デフォルトは 1 ページあたり 10 個のデータ)。

        vue のライフサイクル関数では、すべてのデータを取得して、合計データの変数: に格納し、tableDataメソッドを呼び出してqueryByPage合計データをインターセプトします. デフォルトでは、10 個のデータがインターセプトされます (インデックスは 0-9 です) )、傍受されたデータは実際にデータを表示する変数に保存されますpageDataここでは、10個のデータが立ち上がり次第表示されます.現在のページまたは各ページのサイズを変更する場合は、変数currentPageまたはpageSizeを変更し、それを実行してqueryByPage目的のフラグメントをインターセプトします.

具体的なqueryByPage方法は、次のことを達成する方法です。

  • 最初のページと 1 ページあたり 10 個のデータを表示する場合: インデックス0-9データを傍受する必要があります (つまりtableData.slice(0, 10)=> currentPage = 1;pageSize = 10)。
  • 最初のページと 1 ページあたり 20 個のデータを表示する場合: インデックス0-19データを傍受する必要があります (つまりtableData.slice(0, 20)=> currentPage = 1;pageSize = 20)。
  • 1 ページあたり 10 個のデータを含むページ 2 を表示する場合: 索引付けされた10-19データをインターセプトする必要があります (つまりtableData.slice(10, 20)=> currentPage = 2;pageSize = 20)。

この時点で、次の式を導入できます: tableData.slice((currentPage - 1) x pageSize, currentPage x pageSize)

Vue2 バージョン

<template>
  <el-card class="box-card">
    <div slot="header" class="clearfix">
      <span>vue2实现前端分页</span>
    </div>
    <el-table
        :data="pageData"
        border
        size="mini"
        style="width: 100%">
        <el-table-column prop="name" label="姓名" width="120" align="center" />
        <el-table-column prop="age" label="年龄" width="80" align="center" />
        <el-table-column prop="describe" label="描述" align="center" />
      </el-table>

      <el-pagination
        style="margin-top: 12px;text-align: right;"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[10, 20, 50, 100]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pageTotal">
      </el-pagination>
  </el-card>
</template>

<script>
import axios from 'axios'
export default {
      
      
  data () {
      
      
    return {
      
      
      // 总的数据
      tableData: [],
      // 分页的数据
      pageData: [],
      // 总数据量 默认为 0
      pageTotal: 0,
      // 当前页 默认是第一页
      currentPage: 1,
      // 每页大小 默认每页10条数据
      pageSize: 10
    }
  },
  created () {
      
      
    this.fetchData()
  },
  methods: {
      
      
    // 改变每页大小的回调
    handleSizeChange (val) {
      
      
      this.pageSize = val

      this.pageData = this.queryByPage()
    },
    // 改变当前页的回调
    handleCurrentChange (val) {
      
      
      this.currentPage = val

      this.pageData = this.queryByPage()
    },
    // 获取全部数据
    async fetchData () {
      
      
      // pubic/table_data.json :默认请求后端数据
      const {
      
       data } = await axios.get('/table_data.json')

      this.tableData = data.data
      this.pageTotal = data.data.length

      this.pageData = this.queryByPage()
    },
    // 实现分页的方法
    queryByPage () {
      
      
      // 起始位置 = (当前页 - 1) x 每页的大小
      const start = (this.currentPage - 1) * this.pageSize
      // 结束位置 = 当前页 x 每页的大小
      const end = this.currentPage * this.pageSize

      return this.tableData.slice(start, end)
    }
  }
}
</script>

Vue3版

<script setup lang="ts">
	import axios from "axios"
	import {
      
       reactive, onMounted } from "vue"

	// 表格数据接口
	interface ITable {
      
      
		name: string;
		age: number;
		describe: string;
	}

	let data = reactive({
      
      
		tableData: [] as ITable[],  // 总的数据
		pageData: [] as ITable[],   // 分页的数据
		currentPage: 1, // 当前页 默认是第一页
		pageSize: 10,   // 每页大小 默认每页10条数据
		pageTotal: 0 		// 总数据量 默认为 0
	})

	// 在声明周期函数获取数据
	onMounted(() => {
      
      
		fetchData()
	})

	const fetchData = async () => {
      
      
		// pubic/table_data.json :默认请求后端数据
		const result = await axios.get("/table_data.json")

		data.tableData = result.data.data
		data.pageTotal = result.data.data.length

		data.pageData = queryByPage()
	}

	// 实现分页的方法
	const queryByPage = (): ITable[] => {
      
      
		// 起始位置 = (当前页 - 1) x 每页的大小
		let start = (data.currentPage - 1) * data.pageSize
		// 结束位置 = 当前页 x 每页的大小
		let end = data.currentPage * data.pageSize

		// 返回切割数组后的数据
		return data.tableData.slice(start, end)
	}

	// 改变每页大小的方法
	const handleSizeChange = (val: number) => {
      
      
		data.pageSize = val
		
		data.pageData = queryByPage()
	}

	// 改变当前页的方法
	const handleCurrentChange = (val: number) => {
      
      
		data.currentPage = val
		
		data.pageData = queryByPage()
	}
</script>

<template>
	<el-card class="box-card" style="width: 70%;">
    <template #header>
      <div class="card-header">
        <span>vue3实现前端分页</span>
      </div>
    </template>
		<el-table :data="data.pageData" border style="width: 100%;">
    <el-table-column prop="name" label="姓名" width="150" align="center" />
    <el-table-column prop="age" label="年龄" width="80" align="center" />
    <el-table-column prop="describe" label="描述" align="center" />
  </el-table>
	<el-pagination
		v-model:currentPage="data.currentPage"
		v-model:page-size="data.pageSize"
		:page-sizes="[10, 20, 50, 100]"
		:background="true"
		layout="total, sizes, prev, pager, next, jumper"
		:total="data.pageTotal"
		@size-change="handleSizeChange"
		@current-change="handleCurrentChange"
		style="margin-top: 12px;display: flex;justify-content: flex-end;"
	/>
  </el-card>
</template>

| |ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_48165407/article/details/126790480