序文
実際の開発では、ほとんどのページングはバックエンドで行われます。しかし、そうでない場合もあれば、そうでない場合もあります。バックエンドは一度にすべてのデータを返します。フロントエンドですべてのデータを表示することは不可能ですが、ページング効果を作成することはできません。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. テーブル内のデータが十分な場合は、ページング効果も作成する必要があります。
次に、配列内のメソッドを使用して、slice
Vue でフロントエンドのページング効果を実現します。
原理
フロントエンドのページネーションを実装することは難しくありません.配列を必要とするメソッドを使用してください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>
| |