分页和过滤单独运行/ Vue [英] pagination and filter separately running / Vue

查看:49
本文介绍了分页和过滤单独运行/ Vue的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我获取并对数据进行分页,没问题。但是当我尝试过滤数据时,分页不适用于过滤后的数据。仍在底部显示下一页。当我去(例如)第2页时,第二页没有数据。因为我已经过滤了它。我该如何解决这个问题?谢谢!

I fetch and do pagination on the data, no problem with that. But when I try to filter the data, the pagination not working with the filtered data. Still displaying next pages at bottom. And when I go(for example) page 2 there is no data in page two. Because I filtered it already. How can I fix this problem? Thank you!

索引组件

Data(){
    meta_data: {
          last_page: null,
          current_page: 1,
          prev_page_url: null
     }
},
methods: {
    fetchEstates(page = 1){
        axios.get('/ajax', {
            params: {
                page
            }}).then((response) => {
                // console.log(response);
                this.estates = response.data.data;
                this.insertMarkers();
                this.meta_data.last_page = response.data.last_page;
                this.meta_data.current_page = response.data.current_page;
                this.meta_data.prev_page_url = response.data.prev_page_url;
        });
    },
},

computed: {
    one: function () {
        let filteredStates = this.estates.filter((estate) => {
            return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
            (this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
            (this.regions.length === 0 || this.regions.includes(estate.region))});

            if(this.sortType == 'price') {
                filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
            }
            if(this.sortType == 'created_at') {
                filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
            }

            filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
            filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
            filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});

            return filteredStates;
    },
}

<pagination
      :meta_data="meta_data"
      v-on:next="fetchEstates">
</pagination>

分页组件

    props: ['meta_data'],
    methods: {
        next(page) {
            this.$emit('next', page);
        }
    }
}

    <nav>
         <ul class="pagination pagination-lg">
             <li class="page-item"
                 :class="{ 'disabled': meta_data.prev_page_url === null }">
                 <a href="#"
                     class="page-link"
                     @click="next(meta_data.current_page-1)">
                     &laquo;
                 </a>
             </li>
             <li class="page-item"
                 v-for="page in meta_data.last_page"
                 :key="page"
                 :class="{ 'active':meta_data.current_page === page }">
                 <a href="#"
                     @click.prevent="next(page)"
                     class="page-link">
                     {{ page }}
                 </a>
             </li>
             <li class="page-item"
                 :class="{ 'disabled': meta_data.current_page === meta_data.last_page }">
                <a  href="#"
                     class="page-link"
                     @click="next(meta_data.current_page+1)">
                     &raquo;
                </a>
             </li>
        </ul>
    </nav>

推荐答案

<你做错了你应该将数据发送到后端/ sql然后在那里过滤它们。
所以你得到了正确的 last_page 等等。

无论如何你还想过滤它们作为它的是的,您将需要计算页面agen。

Anyway if you still want to filter them as its is, you will need to calculate the pages agen.

这是一个示例,因此您可以计算 filteredStates 并生成页面,您可能已经能够生成它们,但计算可以帮助您。

Here is a sample, so you could calculate how many pages in filteredStates and generate pages, you may already able to generate them but the calculation could help you.

Data(){
// you should use data only :) eg data:function()  { return  meta_data }
// but if this work for you i gusse its fine.
    meta_data: {
          totalPages: null,
          current_page: 1,
          pageSize: 20,// how many items exist per page
          pagedItems: [], // paged items eg when you click prev or next
          filteredData:[], // total items
          prevClass: "",
          nextClass: "",
          pages:[]
         
     }
},
methods: {
    // this will init the paginations and display the data
    getData: function(){
    // totalpages 
      this.meta_data.totalPages = Math.ceil(this.meta_data.filteredData.length / this.meta_data.pageSize);
       // items for the current selected Page
       this.meta_data.pagedItems = 
       this.meta_data.filteredData.slice(this.meta_data.pageSize * (this.meta_data.current_page -1),this.meta_data.pageSize);
       
       if (this.meta_data.current_page == this.meta_data.totalPages
       || this.meta_data.totalPages <=1)
           this.meta_data.nextClass = "disabled";
           else this.meta_data.nextClass = "";
           
      if (this.meta_data.current_page <=1)
           this.meta_data.prevClass = "disabled";
           else this.meta_data.prevClass = "";
           
           this.calPages();
     
    },
    
    toPage:function(page){
      this.meta_data.current_page = page;
      this.getData();
    },
    
    next: function(){
     if (this.meta_data.totalPages >= this.meta_data.current_page +1){
         this.meta_data.current_page++;
         this.getData();
         }
         
        return false;
    },
    
    prev: function(){
     if (this.meta_data.current_page -1 >=1 ){
          this.meta_data.current_page--;
          this.getData();
         }
         
        return false;
    },
    // this will generate [counter] pages each time you select a page.
    // I wrote this a long time ago for one of my application
    calPages: function(){
      if (this.meta_data.totalPages<=0)
          return false;
      var start = this.meta_data.current_page;
			var end = this.meta_data.current_page;
			var counter = 3;
      //If the page cannot be devised by counter enter the loop
			if ((start % counter != 0) && (end % counter != 0)) {
				//Get the next nearest page that is divisible by 5
				while ((end % counter) != 0) {
					end++;
				}
				//Get the previous nearest page that is divisible by counter
				while ((start % counter) != 0) {
					start--;
				}

			}
			//The page is divisible by counter so get the next counter pages in the pagination
			else {
				end += counter;
			}
			//We are on the first page
			if (start == 0) {
				  start++;
				  end++;
			}



			//We are on the last page
			if (end == this.meta_data.totalPages || end > this.meta_data.totalPages) {
				end = this.meta_data.totalPages ;
			}

			if (start == this.meta_data.current_page && start > 1)
				start--;

			while (end - start < counter && end - start > 0)
				start--;


			if (start <= 0)
				start = 1;

			while (end - start > counter)
				end--;
       var r =[];
       
       for (var i = start; i <= end; i++)
            r.push({ page:i, selected:(this.meta_data.current_page == i? "selected" : "") });
            
          this.meta_data.pages = r;
    }

    fetchEstates(page = 1){
        axios.get('/ajax', {
            params: {
                page
            }}).then((response) => {
                // console.log(response);
                this.estates = response.data.data;
                this.insertMarkers();
                //this.meta_data.last_page = response.data.last_page;
                //this.meta_data.current_page = response.data.current_page;
                //this.meta_data.prev_page_url = response.data.prev_page_url;
        });
    },
},

computed: {
    // dont see where you are calling this?
    one: function () {
        let filteredStates = this.estates.filter((estate) => {
            return (this.keyword.length === 0 || estate.address.includes(this.keyword)) &&
            (this.rooms.length === 0 || this.rooms.includes(estate.rooms)) &&
            (this.regions.length === 0 || this.regions.includes(estate.region))});

            if(this.sortType == 'price') {
                filteredStates = filteredStates.sort((prev, curr) => prev.price - curr.price);
            }
            if(this.sortType == 'created_at') {
                filteredStates = filteredStates.sort((prev, curr) => Date.parse(curr.created_at) - Date.parse(prev.created_at));
            }

            filteredStates = filteredStates.filter((estate) => { return estate.price <= this.slider.value});
            filteredStates = filteredStates.filter((estate) => { return estate.extend <= this.sliderX.value});
            filteredStates = filteredStates.filter((estate) => { return estate.m2_price <= this.sliderT.value});
            
this.meta_data.filteredData = filteredStates;
this. getData()// this will init the paginations and display the data 
return filteredStates;
    },
}

 <nav>
         <ul class="pagination pagination-lg">
             <li class="page-item"
                 :class="meta_data.prevClass">
                 <a href="#"
                     class="page-link"
                     v-on:click="prev">
                     &laquo;
                 </a>
             </li>
             <li class="page-item"
                 v-for="page in meta_data.pages" :key="page"
                 :class="page.selected">
                 <a href="#"
                     v-on:click="toPage(page.page)"
                     class="page-link">
                     {{ page.page }}
                 </a>
             </li>
             <li class="page-item" :class="meta_data.prevClass" v-on:click="next" >
                <a href="#"
                     class="page-link"
                     @click="next">
                     &raquo;
                </a>
             </li>
        </ul>
    </nav>

这篇关于分页和过滤单独运行/ Vue的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆