javascript - 分页和过滤分别运行/Vue

标签 javascript vue.js vuejs2

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

索引组件

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 等等。

无论如何,如果您仍想按原样过滤它们,则需要计算页面代理。

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

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>

关于javascript - 分页和过滤分别运行/Vue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54565731/

相关文章:

javascript - 如何在 nuxtjs 中映射子状态

javascript - Bootstrap-vue - 动态设置表变量

javascript - 如何为给定情况定义 knockout 数据模型?

javascript - 递归 .children() 以搜索 id 属性

javascript - Vue.js 中的 'data:' 和 'data()' 有什么区别?

vue.js - vue : add multiple classes inside a v-for, 基于数组

javascript - 使用渲染功能时 Vue 组件不显示子文本节点

javascript - Vue.js async/await 与 then 函数不执行

javascript - 如何为 div 中的所有元素设置点击处理程序

javascript - IE9(和其他 IE 版本)的 AJAX 问题