最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue + element-ui的分頁(yè)問題實(shí)現(xiàn)

 更新時(shí)間:2018年12月17日 10:21:11   作者:ma125120  
這篇文章主要介紹了vue + element-ui的分頁(yè)問題實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

背景介紹

最近比較空閑,公司的后臺(tái)就想著把現(xiàn)在的后臺(tái)管理系統(tǒng)給改版一下,說(shuō)是以前的太難看了,用著也不好用,然后給我甩過(guò)來(lái)一個(gè)ant-design-pro的鏈接,說(shuō)是他看這個(gè)就挺不錯(cuò)的。

我當(dāng)時(shí)心里就想著,之前的那個(gè)項(xiàng)目混合在你們的java項(xiàng)目里,跟普通的jsp頁(yè)面差不多,一下就是一大堆的css和js文件,看著我都害怕(好吧,我承認(rèn)其實(shí)我都不敢看),這能加載的快了就奇了怪了。ant-design最初是為react設(shè)計(jì)的,ant-design-pro自然也是用react了,不得不說(shuō)人家這個(gè)界面看著確實(shí)舒服。

對(duì)著ant-design-pro的官方文檔看了一通,貌似看了跟沒看也差不多???算了,還是直接看代碼吧,整理了一下思路,大致上是看懂了,除了react + react-router外,狀態(tài)管理用的是 dva, redux的異步問題算是解決了,要不就開始直接寫頁(yè)面吧?

等等,我好像漏掉了點(diǎn)什么?噢,對(duì),先看看打包出來(lái)的文件大小,一打包我的心就涼了,最大的js居然有900多k,ant-design的源文件是真的大。react我還只是能寫出代碼,打包優(yōu)化這個(gè)可就有點(diǎn)為難我了。這時(shí)的我再想到公司那1m的帶寬,還有這幾個(gè)后臺(tái)的技術(shù)能力,要不然這個(gè)技術(shù)棧我還是放棄吧?不能指望連 請(qǐng)求頭, CORS稍微高級(jí)一點(diǎn)的攜帶cookie, nginx靜態(tài)服務(wù)器 都搞不懂的人去給我弄個(gè)靜態(tài)服務(wù)器,再順便開啟一下gzip吧?算了算了,找找有沒有vue + element-ui的后臺(tái)模板,不用太費(fèi)勁就找到了 vue-element-admin

vue-element-admin用著還行,就是界面不太符合我的理想情況,就對(duì)著ant-design-pro改造了一點(diǎn),列表頁(yè)大概就是下面這樣了。列表的數(shù)據(jù)是要分頁(yè)的,普通的列表頁(yè)只有一個(gè)頁(yè)面棧,也就是用戶點(diǎn)擊地址欄的回退地址欄時(shí),會(huì)返回上一個(gè)頁(yè)面棧,而不是上一頁(yè)的數(shù)據(jù),不太符合用戶習(xí)慣吧?畢竟傳統(tǒng)的網(wǎng)站都是可以回退到上一頁(yè)的,嗯,話不多說(shuō),進(jìn)入正題吧。

 

第一步:改變地址欄

假設(shè)列表頁(yè)的路徑是 /user/list,分頁(yè)相關(guān)的參數(shù)為 { page: 1, pagesize: 10 } ,從其他頁(yè)面跳轉(zhuǎn)過(guò)來(lái)的時(shí)候,我們的路徑通常是不包含任何參數(shù)的,之后的列表數(shù)據(jù)都是根據(jù)該頁(yè)面的page和pagesize進(jìn)行變化的,當(dāng)未使用keep-alive緩存組件時(shí),每次進(jìn)入列表頁(yè)都相當(dāng)于第一次進(jìn)入,也就是說(shuō)每次都只能獲取第一頁(yè)的數(shù)據(jù)。

既然列表數(shù)據(jù)是用page和pagesize進(jìn)行變化的,那直接從地址欄獲取page和pagesize進(jìn)行賦值不就好了?那么是改變地址欄的代碼是直接寫在當(dāng)前頁(yè)面還是 獨(dú)立為分頁(yè)組件 呢?從復(fù)用性方面來(lái)說(shuō),還是獨(dú)立出來(lái)的好,畢竟其他頁(yè)面可能也會(huì)使用到,總不能每次都復(fù)制粘貼吧,那組件化的意義何在?當(dāng)然了,也不是說(shuō)分頁(yè)就必須用這個(gè)自定義的分頁(yè)組件,只推薦在 主頁(yè)面(非遮罩層 ,有的頁(yè)面會(huì)在點(diǎn)擊某一行數(shù)據(jù)時(shí)出現(xiàn)遮罩層顯示子列表,此時(shí)使用element-ui的分頁(yè)組件即可)需要分頁(yè)時(shí)使用。

當(dāng)改變地址欄的時(shí)候,我們是不希望不帶分頁(yè)參數(shù)的頁(yè)面棧存在的,此時(shí)用replace直接替換即可。

MyPagination.vue的初始結(jié)構(gòu)為:

<template>
 <div class = " flex all-center">
 <template v-if="total > 0">
  <el-pagination
  :page-size="pagesize"
  :total="total"
  :current-page="page"
  background
  layout="prev, pager, next, jumper, total"
  class="my-pagination"
  @current-change="changePage" />
 </template>
 </div>
</template>

<script>
export default {
 name: 'MyPagination',
 props: {
 total: {
  type: Number,
  default: 0,
 },
 page: {
  type: Number,
  default: 1,
 },
 pagesize: {
  type: Number,
  default: 10,
 },
 totalPages: {
  type: Number,
  default: 1,
 },
 },
 created() {
 this.getCurrentPage();
 },
 methods: {
 changePage(val) {
  this.handlePage('push', val, this.pagesize);
  this.$emit('change', val, this.pagesize);
 },
 getCurrentPage() {
  var { page, pagesize } = this.$route.query;
  if (!page || !pagesize) {
  this.handlePage('replace', page || 1, +pagesize || this.pagesize);
  return true;
  }
  return false;
 },
 handlePage(type, page, pagesize) {
  this.$router[type]({
  path: this.$route.path,
  query: { ...this.$route.query, page, pagesize },
  });
 }
 },
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.my-pagination {
 padding-top: 24px; 
}
</style>

父組件的關(guān)鍵代碼:

<MyPagination :total = "total" :pagesize = "pagesize" :page="page" :totalPages = "totalPages" @change = "changePage" />

methods: {
 changePage(page, pagesize) {
  var _page = this.page,
   _pagesize = this.pagesize;
  this.page = page;
  this.pagesize = pagesize;
  if (page !== _page && pagesize || _pagesize !== pagesize) this.fetchData(); // 非首次進(jìn)入頁(yè)面時(shí)再獲取分頁(yè)數(shù)據(jù),因?yàn)樵赾reated鉤子中已經(jīng)獲取過(guò)一次了。
 },
}

實(shí)現(xiàn)效果: 首次進(jìn)入該頁(yè)面時(shí),如果不含有分頁(yè)參數(shù),就會(huì)先改變分頁(yè)參數(shù),然后再獲取數(shù)據(jù),之后點(diǎn)擊分頁(yè)組件的頁(yè)碼也會(huì)獲取分頁(yè)之后的數(shù)據(jù)。

第二步: 觀察路由變化

上一步的實(shí)現(xiàn)效果乍一看好像沒什么不對(duì)勁的地方,但是如果直接改變地址欄的話,顯示的當(dāng)前頁(yè)和當(dāng)前數(shù)據(jù)都不會(huì)變化。前端路由在頁(yè)面的查詢參數(shù)(指的是 router的查詢參數(shù) ,可不是普通頁(yè)面的查詢參數(shù))變化時(shí),默認(rèn)是不會(huì)重新加載的,除非頁(yè)面的key發(fā)生變化,這樣是為了盡可能的防止頁(yè)面重新渲染,所以就不用key的方式解決了,直接通過(guò)vue的watch檢測(cè) $route 的變化,從而改變當(dāng)前頁(yè)和當(dāng)前數(shù)據(jù)的顯示問題。

在MyPagination.vue中新增:

watch: {
 '$route'(to, from) {
  let { page, pagesize } = to.query;
  if (!this.getCurrentPage()) {
  this.$emit('change', +page || 1, +pagesize || 10);
  }
 }
},

第三步: 控制pagesize的大小

在上一步的效果中,當(dāng)改變地址欄的page和pagesize時(shí),列表頁(yè)的數(shù)據(jù)也會(huì)隨之變化。既然是根據(jù)地址欄的參數(shù)變化,那么新的問題就產(chǎn)生了,

如果用戶輸入的page大于頁(yè)面總數(shù)呢?

這個(gè)時(shí)候主要就看后臺(tái)怎么設(shè)計(jì)了,

返回第一頁(yè)的數(shù)據(jù)。

getCurrentPage() {
 var { page, pagesize } = this.$route.query;
 /* 
 (totalPages > 0 && (page > totalPages));滿足總頁(yè)數(shù)大于0且當(dāng)前頁(yè)大于總頁(yè)數(shù)時(shí),跳轉(zhuǎn)到第一頁(yè)
 */
 if (!page || !pagesize || (totalPages > 0 && (page > totalPages))) {
 this.handlePage('replace', page || 1, this.pagesize);
 return true;
 }
 return false;
},

返回最后一頁(yè)的數(shù)據(jù)(我覺得這種操作應(yīng)該是比較合理的)。

getCurrentPage() {
 var { page, pagesize } = this.$route.query,
  MAX_PAGESIZE = this.max,
  totalPages = this.totalPages;
 if (!page || !pagesize) {
 this.handlePage('replace', page || 1, +pagesize || this.pagesize);
 return true;
 } else if (totalPages > 0 && (page > totalPages)) {
 this.handlePage('replace', totalPages, +pagesize);
 return true;
 }
 return false;
},

替換當(dāng)前頁(yè)面棧,return true的作用是阻止watch中的后續(xù)操作,取消本次請(qǐng)求。替換頁(yè)面以后,請(qǐng)求遠(yuǎn)程數(shù)據(jù),更新當(dāng)前頁(yè)和數(shù)據(jù)的顯示。

返回空數(shù)組(可能大多數(shù)后臺(tái)都是這么設(shè)計(jì)的,他們應(yīng)該沒想過(guò)page會(huì)大于總頁(yè)數(shù)吧)。 代碼與2中的一樣。

上文都是建立在totalPages已確定的情況,如果是首次進(jìn)入頁(yè)面的話情況就會(huì)不一樣了。

如果是首次進(jìn)入頁(yè)面的話,totalPages第一次是0,也就是地址欄的參數(shù)將不會(huì)發(fā)生變化,這時(shí)候就會(huì)出現(xiàn)地址欄和分頁(yè)組件的顯示不一致的情況。這時(shí)候可以在分頁(yè)組件中watch totalPages的變化。

totalPages(newVal, oldVal) {
 if (+oldVal === 0 && newVal > 0) {
 this.handlePage('replace', this.page, +this.pagesize);
 }
}

如果pagesize過(guò)大呢?

pagesize是必須要進(jìn)行限制的,如果太大的話,后臺(tái)查詢數(shù)據(jù)就會(huì)非常慢,也可能會(huì)造成壓力。 解決辦法其實(shí)也簡(jiǎn)單,就是在props增加一個(gè)max屬性,然后在getCurrentPage方法中進(jìn)行限制,代碼如下:

props: {
 max: {
  type: Number,
  default: 20,
 },
},
methods: {
 getCurrentPage() {
  var { page, pagesize } = this.$route.query,
   MAX_PAGESIZE = this.max,
   totalPages = this.totalPages;
  if (!page || !pagesize) {
  this.handlePage('replace', page || 1, +pagesize || this.pagesize);
  return true;
  } else if (pagesize > MAX_PAGESIZE) {
  this.handlePage('replace', page, MAX_PAGESIZE);
  return true;
  } else if (totalPages > 0 && (page > totalPages)) {
  this.handlePage('replace', totalPages, +pagesize);
  return true;
  }
  return false;
 },
},

第四步: 優(yōu)化代碼

點(diǎn)擊分頁(yè)組件的頁(yè)碼時(shí)產(chǎn)生兩次請(qǐng)求

點(diǎn)擊分頁(yè)組件時(shí),1. 會(huì)監(jiān)聽current-change事件并改變地址欄,同時(shí)emit change事件至父組件,2. 但是地址欄改變后,在watch $route也會(huì)emit change事件至父組件,那么只需要合并emit change事件,即current-change事件中只改變地址欄。

changePage(val) {
 this.handlePage('push', val, this.pagesize);
},

結(jié)果

至此,一個(gè)自定義的分頁(yè)組件就已經(jīng)實(shí)現(xiàn)了,改變地址欄的參數(shù)就可以看到分頁(yè)數(shù)據(jù)的變化了,點(diǎn)擊頁(yè)碼時(shí)地址欄也會(huì)隨之而改變,請(qǐng)求數(shù)量已經(jīng)盡可能的減少了。

自定義的分頁(yè)組件: MyPagination.vue

列表頁(yè): list.vue

完整demo: front_end

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue中如何使用mock模擬數(shù)據(jù)

    Vue中如何使用mock模擬數(shù)據(jù)

    這篇文章主要介紹了Vue中如何使用mock模擬數(shù)據(jù),具有很好的價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • vue-cli的eslint相關(guān)用法

    vue-cli的eslint相關(guān)用法

    本篇文章主要介紹了vue-cli的eslint相關(guān)用法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • 詳解Vue項(xiàng)目在其他電腦npm run dev運(yùn)行報(bào)錯(cuò)的解決方法

    詳解Vue項(xiàng)目在其他電腦npm run dev運(yùn)行報(bào)錯(cuò)的解決方法

    這篇文章主要介紹了詳解Vue項(xiàng)目在其他電腦npm run dev運(yùn)行報(bào)錯(cuò)的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • 詳解Vue底部導(dǎo)航欄組件

    詳解Vue底部導(dǎo)航欄組件

    這篇文章主要介紹了Vue底部導(dǎo)航欄的詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • vue?代碼壓縮優(yōu)化方式

    vue?代碼壓縮優(yōu)化方式

    這篇文章主要介紹了vue?代碼壓縮優(yōu)化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • vue柱狀進(jìn)度條圖像的完美實(shí)現(xiàn)方案

    vue柱狀進(jìn)度條圖像的完美實(shí)現(xiàn)方案

    本文是對(duì)bar進(jìn)度條實(shí)現(xiàn)的2種方案進(jìn)行分享,第一種是很簡(jiǎn)單,純css的實(shí)現(xiàn),第二種是echart的實(shí)現(xiàn)。對(duì)vue柱狀進(jìn)度條圖像的實(shí)現(xiàn)方案,感興趣的朋友跟隨小編一起看看吧
    2019-08-08
  • vue-cli3+typescript新建一個(gè)項(xiàng)目的思路分析

    vue-cli3+typescript新建一個(gè)項(xiàng)目的思路分析

    這篇文章主要介紹了vue-cli3+typescript新建一個(gè)項(xiàng)目的思路,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Vuex報(bào)錯(cuò)之[vuex] unknown mutation type: handlePower問題及解決

    Vuex報(bào)錯(cuò)之[vuex] unknown mutation type: han

    這篇文章主要介紹了Vuex報(bào)錯(cuò)之[vuex] unknown mutation type: handlePower問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Vue插件從封裝到發(fā)布的完整步驟記錄

    Vue插件從封裝到發(fā)布的完整步驟記錄

    這篇文章主要給大家介紹了關(guān)于Vue插件從封裝到發(fā)布的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼

    VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼

    這篇文章主要介紹了VUE使用DXFParser組件解析dxf文件生成圖片的操作代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09

最新評(píng)論

颍上县| 眉山市| 涡阳县| 达州市| 浮山县| 芜湖县| 苗栗县| 高邑县| 沙田区| 深州市| 凉山| 云和县| 来凤县| 福清市| 敦化市| 交城县| 察哈| 楚雄市| 闽清县| 体育| 林芝县| 定南县| 唐海县| 监利县| 满洲里市| 泗阳县| 庄浪县| 晋江市| 云林县| 新田县| 新竹县| 临海市| 疏附县| 祁门县| 德保县| 图木舒克市| 莆田市| 温泉县| 大连市| 天长市| 普定县|