Php 如何使用vue js和laravel在列表页面中添加分页?

Php 如何使用vue js和laravel在列表页面中添加分页?,php,laravel,vue.js,Php,Laravel,Vue.js,我有一个使用vue js和laravel的列表页面。本页面还包括过滤和排序功能。目前,列表、排序和筛选工作正常。我需要在这个列表页面中包含分页。我不知道该怎么写,我的客户需要这个。我在vue js方面没有太多经验。我目前的代码如下。请检查并帮助我整合分页,好吗 版本是vue js(1.0.25)和laravel(5.2) dashboard.blade.php @extends('layouts.app') @section('title', 'Dashboard') @section('s

我有一个使用vue js和laravel的列表页面。本页面还包括过滤和排序功能。目前,列表、排序和筛选工作正常。我需要在这个列表页面中包含分页。我不知道该怎么写,我的客户需要这个。我在vue js方面没有太多经验。我目前的代码如下。请检查并帮助我整合分页,好吗

版本是vue js(1.0.25)和laravel(5.2)

dashboard.blade.php

@extends('layouts.app')

@section('title', 'Dashboard')

@section('style')
    <style>
        th.active .arrow {
            opacity: 1;
        }

        .arrow {
            display: inline-block;
            vertical-align: middle;
            width: 0;
            height: 0;
            margin-left: 5px;
            opacity: 0.66;
        }

        .arrow.asc {
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-bottom: 4px solid #42b983;
        }

        .arrow.dsc {
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-top: 4px solid #42b983;
        }

        #search {
            margin-bottom: 10px;
        }
    </style>
@endsection

@section('content')
    <div class="container">
        <div class="row">
            <h1 class="page-header">{{ trans('messages.customerListPageHeadingLabel') }}</h1>
            <template id="grid-template">
                <table class="table table-hover table-bordered">
                    <thead>
                    <tr>
                        <th v-for="key in columns" @click="sortBy(key)" :class="{active: sortKey == key}">@{{ heading[key] }} <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="(index, customer) in customers | filterBy filterKey | orderBy sortKey sortOrders[sortKey]">
                        <td>@{{ customer.erp_id }}</td>
                        <td>@{{customer.firstname}}</td>
                        <td><a href="{{ url('/customer/details/') }}/@{{ customer.id }}">@{{customer.lastname}}</a></td>
                        <td>@{{customer.email}}</td>
                        <td>@{{customer.phone_1}}</td>
                        <td>@{{customer.status}}</td>
                        <td>@{{customer.created_on}}</td>
                    </tr>
                    </tbody>
                </table>
            </template>
            <div id="app">
                <div class="form-group col-md-4">
                    <form id="search" class="form-inline">
                        <label for="query">{{ trans('messages.customerListPageSearchBox') }} </label>
                        <input name="query" class="form-control" v-model="searchQuery">
                    </form>
                </div>
                <br>
                <customer-grid  :customers="{{$listCustomers}}"  :columns="gridColumns" :heading="colTitles"  :filter-key="searchQuery"></customer-grid>
            </div>
        </div>
    </div>
    @endsection

    @push('script')
            <!-- Vue Js -->
    <script src="/assets/js/vue.js"></script>
    <script src="/assets/js/vue-resource.js"></script>
    <script>
        Vue.component('customer-grid', {
            template: '#grid-template',
            props: {
                customers: Array,
                columns: Array,
                filterKey: String,
                heading:Object
            },

            data: function () {
                var sortOrders = {}
                this.columns.forEach(function (key) {
                    sortOrders[key] = 1
                })
                return {
                    sortKey: '',
                    sortOrders: sortOrders
                }
            },
            methods: {
                sortBy: function (key) {
                    this.sortKey = key
                    this.sortOrders[key] = this.sortOrders[key] * -1
                }
            }
        })

        // bootstrap the demo
        var demo = new Vue({
            el: '#app',
            data: {
                searchQuery: '',
                gridColumns: ['erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', 'created_on'],
                gridData: null,
                colTitles: {'erp_id':'@lang('messages.customerListPageTableCustomerNo')', 'firstname':'@lang('messages.customerListPageTableFirstname')', 'lastname':'@lang('messages.customerListPageTableLastname')', 'email':'E-Mail', 'phone_1':'@lang('messages.customerListPageTablePhone')', 'status':'Status', 'created_on':'@lang('messages.customerListPageTableAddedDate')'}
            },

            created: function() {
                this.fetchData()
            },

            methods: {
                fetchData: function () {
                    var self = this;
                    $.get('/', function( data ) {
                        self.gridData = data;
                    });
                }
            }
        });
    </script>
    @endpush
Route::get('/', ['as' => 'listCustomersPage', 'uses' => 'CustomerController@index']);
public function index()
    {
        $listCustomers    = Customer::select('id', 'erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', DB::raw("DATE_FORMAT(created_at, '%d.%m.%Y %H:%i') AS created_on"))
            ->orderBy('id', 'desc')
            ->get();
        return view('dashboard', compact('listCustomers'));
        /*return view('dashboard');*/
    }
CustomerController.php

@extends('layouts.app')

@section('title', 'Dashboard')

@section('style')
    <style>
        th.active .arrow {
            opacity: 1;
        }

        .arrow {
            display: inline-block;
            vertical-align: middle;
            width: 0;
            height: 0;
            margin-left: 5px;
            opacity: 0.66;
        }

        .arrow.asc {
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-bottom: 4px solid #42b983;
        }

        .arrow.dsc {
            border-left: 4px solid transparent;
            border-right: 4px solid transparent;
            border-top: 4px solid #42b983;
        }

        #search {
            margin-bottom: 10px;
        }
    </style>
@endsection

@section('content')
    <div class="container">
        <div class="row">
            <h1 class="page-header">{{ trans('messages.customerListPageHeadingLabel') }}</h1>
            <template id="grid-template">
                <table class="table table-hover table-bordered">
                    <thead>
                    <tr>
                        <th v-for="key in columns" @click="sortBy(key)" :class="{active: sortKey == key}">@{{ heading[key] }} <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
                        </th>
                    </tr>
                    </thead>
                    <tbody>
                    <tr v-for="(index, customer) in customers | filterBy filterKey | orderBy sortKey sortOrders[sortKey]">
                        <td>@{{ customer.erp_id }}</td>
                        <td>@{{customer.firstname}}</td>
                        <td><a href="{{ url('/customer/details/') }}/@{{ customer.id }}">@{{customer.lastname}}</a></td>
                        <td>@{{customer.email}}</td>
                        <td>@{{customer.phone_1}}</td>
                        <td>@{{customer.status}}</td>
                        <td>@{{customer.created_on}}</td>
                    </tr>
                    </tbody>
                </table>
            </template>
            <div id="app">
                <div class="form-group col-md-4">
                    <form id="search" class="form-inline">
                        <label for="query">{{ trans('messages.customerListPageSearchBox') }} </label>
                        <input name="query" class="form-control" v-model="searchQuery">
                    </form>
                </div>
                <br>
                <customer-grid  :customers="{{$listCustomers}}"  :columns="gridColumns" :heading="colTitles"  :filter-key="searchQuery"></customer-grid>
            </div>
        </div>
    </div>
    @endsection

    @push('script')
            <!-- Vue Js -->
    <script src="/assets/js/vue.js"></script>
    <script src="/assets/js/vue-resource.js"></script>
    <script>
        Vue.component('customer-grid', {
            template: '#grid-template',
            props: {
                customers: Array,
                columns: Array,
                filterKey: String,
                heading:Object
            },

            data: function () {
                var sortOrders = {}
                this.columns.forEach(function (key) {
                    sortOrders[key] = 1
                })
                return {
                    sortKey: '',
                    sortOrders: sortOrders
                }
            },
            methods: {
                sortBy: function (key) {
                    this.sortKey = key
                    this.sortOrders[key] = this.sortOrders[key] * -1
                }
            }
        })

        // bootstrap the demo
        var demo = new Vue({
            el: '#app',
            data: {
                searchQuery: '',
                gridColumns: ['erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', 'created_on'],
                gridData: null,
                colTitles: {'erp_id':'@lang('messages.customerListPageTableCustomerNo')', 'firstname':'@lang('messages.customerListPageTableFirstname')', 'lastname':'@lang('messages.customerListPageTableLastname')', 'email':'E-Mail', 'phone_1':'@lang('messages.customerListPageTablePhone')', 'status':'Status', 'created_on':'@lang('messages.customerListPageTableAddedDate')'}
            },

            created: function() {
                this.fetchData()
            },

            methods: {
                fetchData: function () {
                    var self = this;
                    $.get('/', function( data ) {
                        self.gridData = data;
                    });
                }
            }
        });
    </script>
    @endpush
Route::get('/', ['as' => 'listCustomersPage', 'uses' => 'CustomerController@index']);
public function index()
    {
        $listCustomers    = Customer::select('id', 'erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', DB::raw("DATE_FORMAT(created_at, '%d.%m.%Y %H:%i') AS created_on"))
            ->orderBy('id', 'desc')
            ->get();
        return view('dashboard', compact('listCustomers'));
        /*return view('dashboard');*/
    }

我已经用vue.js编写了自己的分页(我也使用vue和laravel),因为vue.js没有开箱即用的分页。 我构建了这个组件:

<style>
    li.page-item {
        cursor: pointer;
    }
    li.active_pagination a {
        background-color: #1c84c6 !important;
        border-color: #1c84c6 !important;
        color: #ffffff !important;
    }
</style>

<template>
    <div>
        <ul class="pagination pull-right">
            <li class="page-item" :class="{'disabled': currentPage == 1}">
                <a class="page-link" href="#" @click.prevent="changeCurrentPage(1)" aria-label="Previous">
                    <span aria-hidden="true">&laquo;</span>
                    <span class="sr-only">Previous</span>
                </a>
            </li>
            <li class="page-item" :class="{'disabled': currentPage == 1}">
                <a class="page-link" href="#" @click.prevent="decrementCurrentPage(currentPage)" aria-label="Previous">
                    <span aria-hidden="true">&lsaquo;</span>
                    <span class="sr-only">Previous</span>
                </a>
            </li>

            <li v-for="index in indexes" class="page-item" :class="{'active_pagination': currentPage == index}"><a class="page-link" @click.prevent="changeCurrentPage(index)">{{index}}</a></li>

            <li class="page-item" :class="{'disabled': currentPage == totalPages}">
                <a class="page-link" href="#" @click.prevent="incrementCurrentPage(currentPage)" aria-label="Next">
                    <span aria-hidden="true">&rsaquo;</span>
                    <span class="sr-only">Next</span>
                </a>
            </li>
            <li class="page-item" :class="{'disabled': currentPage == totalPages}">
                <a class="page-link" href="#" @click.prevent="changeCurrentPage(totalPages)" aria-label="Next">
                    <span aria-hidden="true">&raquo;</span>
                    <span class="sr-only">Next</span>
                </a>
            </li>
        </ul>
    </div>
</template>

<script>

    module.exports = {

        props: ['currentPage','totalPages', 'totalShownIndexes'],

        computed:  {

            indexes: function() {
                var temp_pageIndexes = [];

                if (this.totalPages > 1) {
                    if (this.totalPages <= this.totalShownIndexes) {
                        for (var i = 1; i <= this.totalPages; i++) {
                            if (temp_pageIndexes.indexOf(i) == -1) {
                                temp_pageIndexes.push(i);
                            }
                        }
                    }
                    else {
                        var sigma = Math.ceil((this.totalShownIndexes - 1) / 2);

                        if (sigma + this.currentPage >= this.totalPages) {
                            var temp_right = (this.totalPages - this.currentPage);
                            var temp_left = this.currentPage - (sigma + (sigma - temp_right));

                            temp_pageIndexes.push('...');
                            for (var i = temp_left; i <= this.totalPages; i++) {
                                temp_pageIndexes.push(i);
                            }
                        }
                        else if (this.currentPage - sigma <= 1) {
                            var temp_left = sigma - this.currentPage;
                            var temp_right = sigma + (this.currentPage + sigma + temp_left);

                            for (var i = 1; i <= temp_right - 1; i++) {
                                temp_pageIndexes.push(i);
                            }
                            temp_pageIndexes.push('...');
                        }
                        else {
                            for (var i = this.currentPage - sigma; i <= this.currentPage + sigma; i++) {
                                temp_pageIndexes.push(i);
                            }
                            temp_pageIndexes.push('...');
                        }
                    }
                    return temp_pageIndexes;
                }
                else {
                    this.currentPage = 1;
                    this.totalPages = 1;
                    return ['1'];
                }
            }
        },

        methods: {
            changeCurrentPage(newCurrentPage) {
                console.log('newCurrentPage: ' + newCurrentPage);
                if(newCurrentPage > 0 && newCurrentPage < this.totalPages + 1 && newCurrentPage != this.currentPage && newCurrentPage != '...') {
                    this.currentPage = newCurrentPage;
                    this.$parent.pagination.currentPage = this.currentPage;
                }
            },

            incrementCurrentPage(currentPage) {
                this.changeCurrentPage(Number(currentPage) + 1);
            },

            decrementCurrentPage(currentPage) {
                this.changeCurrentPage(Number(currentPage) - 1)
            }
        }
    }
</script>
您可以将此筛选器放置在筛选/排序列表的末尾,如下所示:

v-for="(index, customer) in customers | filterBy filterKey | orderBy sortKey sortOrders[sortKey] | paginate pagination.currentPage pagination.perPage"
data() {
    return {
        pagination: {
            options: [200,100,50,25,10,1],
            perPage: 10,
            totalPages: 1,
            currentPage: 1,
            totalShownIndexes: 5
        }
    }
}
为此,您需要在数据对象中设置分页对象,如下所示:

v-for="(index, customer) in customers | filterBy filterKey | orderBy sortKey sortOrders[sortKey] | paginate pagination.currentPage pagination.perPage"
data() {
    return {
        pagination: {
            options: [200,100,50,25,10,1],
            perPage: 10,
            totalPages: 1,
            currentPage: 1,
            totalShownIndexes: 5
        }
    }
}
选项属性是可选的。我用它来填充每个页面选择的组合框。因此,您可以选择每页显示多少项。更改选择后,您将设置每页属性

现在你差不多完成了。您只需要以下方法:

changePerPage(perPage) {
    this.pagination.perPage = perPage;
    this.resetCurrentPage();
},

resetCurrentPage() {
    this.pagination.currentPage = 1;
}
只有在希望组合框具有每页选择时,才需要使用
changePerPage()
方法

无论何时应用其他筛选器,都应调用
resetCurrentPage()
方法。这就是你所需要做的


我希望您会觉得这很有用。

分页可以在您雄辩的select语句中完成,现在您所要做的就是在刀片服务器上设置其外观样式编辑客户控制器的内容,如下所示

public function index()
{
    $list = Customer::select('id', 'erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', DB::raw("DATE_FORMAT(created_at, '%d.%m.%Y %H:%i') AS created_on"))
        ->orderBy('id', 'desc')
        ->get();
    $all = count($list);
    $listCustomers = Customer::select('id', 'erp_id', 'firstname',   'lastname', 'email', 'phone_1', 'status', DB::raw("DATE_FORMAT(created_at, '%d.%m.%Y %H:%i') AS created_on"))
        ->orderBy('id', 'desc')
        ->paginate(10);//note here that im assuming you want to display 10 results per page 
    return view('dashboard', compact('listCustomers', 'all'));
    /*return view('dashboard');*/
}
在仪表板刀片上添加将指定不同页面的div

@section('title', 'Dashboard')

@section('style')
<style>
    th.active .arrow {
        opacity: 1;
    }

    .arrow {
        display: inline-block;
        vertical-align: middle;
        width: 0;
        height: 0;
        margin-left: 5px;
        opacity: 0.66;
    }

    .arrow.asc {
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        border-bottom: 4px solid #42b983;
    }

    .arrow.dsc {
        border-left: 4px solid transparent;
        border-right: 4px solid transparent;
        border-top: 4px solid #42b983;
    }

    #search {
        margin-bottom: 10px;
    }
</style>
@endsection

@section('content')
<div class="container">
    <div class="row">
        <h1 class="page-header">{{     trans('messages.customerListPageHeadingLabel') }}</h1>
        <template id="grid-template">
            <table class="table table-hover table-bordered">
                <thead>
                <tr>
                    <th v-for="key in columns" @click="sortBy(key)" :class="{active: sortKey == key}">@{{ heading[key] }} <span class="arrow" :class="sortOrders[key] > 0 ? 'asc' : 'dsc'"></span>
                    </th>
                </tr>
                </thead>
                <tbody>
                <tr v-for="(index, customer) in customers | filterBy filterKey | orderBy sortKey sortOrders[sortKey]">
                    <td>@{{ customer.erp_id }}</td>
                    <td>@{{customer.firstname}}</td>
                    <td><a href="{{ url('/customer/details/') }}/@{{ customer.id }}">@{{customer.lastname}}</a></td>
                    <td>@{{customer.email}}</td>
                    <td>@{{customer.phone_1}}</td>
                    <td>@{{customer.status}}</td>
                    <td>@{{customer.created_on}}</td>
                </tr>
                </tbody>
            </table>
            <div class="w100 categoryFooter"><!--I added this-->
                 <div class="pagination pull-left no-margin-top">
                 {!! $listCustomers->links(null, ['class' => 'pagination no-margin-top']) !!}
            </div>
            <div class="pull-right pull-right col-sm-4 col-xs-12 no-padding text-right text-left-xs">
            <p>Showing 1-10 of {{ $all }} results</p>
            </div>
                        </div>
        </template>
        <div id="app">
            <div class="form-group col-md-4">
                <form id="search" class="form-inline">
                    <label for="query">{{ trans('messages.customerListPageSearchBox') }} </label>
                    <input name="query" class="form-control" v-model="searchQuery">
                </form>
            </div>
            <br>
            <customer-grid  :customers="{{$listCustomers}}"  :columns="gridColumns" :heading="colTitles"  :filter-key="searchQuery"></customer-grid>
        </div>
    </div>
</div>
@endsection

@push('script')
        <!-- Vue Js -->
<script src="/assets/js/vue.js"></script>
<script src="/assets/js/vue-resource.js"></script>
<script>
    Vue.component('customer-grid', {
        template: '#grid-template',
        props: {
            customers: Array,
            columns: Array,
            filterKey: String,
            heading:Object
        },

        data: function () {
            var sortOrders = {}
            this.columns.forEach(function (key) {
                sortOrders[key] = 1
            })
            return {
                sortKey: '',
                sortOrders: sortOrders
            }
        },
        methods: {
            sortBy: function (key) {
                this.sortKey = key
                this.sortOrders[key] = this.sortOrders[key] * -1
            }
        }
    })

    // bootstrap the demo
    var demo = new Vue({
        el: '#app',
        data: {
            searchQuery: '',
            gridColumns: ['erp_id', 'firstname', 'lastname', 'email', 'phone_1', 'status', 'created_on'],
            gridData: null,
            colTitles: {'erp_id':'@lang('messages.customerListPageTableCustomerNo')', 'firstname':'@lang('messages.customerListPageTableFirstname')', 'lastname':'@lang('messages.customerListPageTableLastname')', 'email':'E-Mail', 'phone_1':'@lang('messages.customerListPageTablePhone')', 'status':'Status', 'created_on':'@lang('messages.customerListPageTableAddedDate')'}
        },

        created: function() {
            this.fetchData()
        },

        methods: {
            fetchData: function () {
                var self = this;
                $.get('/', function( data ) {
                    self.gridData = data;
                });
            }
        }
    });
</script>
@endpush
@节(“标题”、“仪表板”)
@节(“样式”)
活动箭头{
不透明度:1;
}
.阿罗{
显示:内联块;
垂直对齐:中间对齐;
宽度:0;
身高:0;
左边距:5px;
不透明度:0.66;
}
.arrow.asc{
左边框:4px实心透明;
右边框:4px实心透明;
边框底部:4px实心#42b983;
}
.arrow.dsc{
左边框:4px实心透明;
右边框:4px实心透明;
边框顶部:4px实心#42b983;
}
#搜寻{
边缘底部:10px;
}
@端部
@节(“内容”)
{{trans('messages.customerListPageHeadingLabel')}
@{{heading[key]}
@{{customer.erp_id}
@{{customer.firstname}
@{{customer.email}
@{{customer.phone_1}}
@{{customer.status}
@{{customer.created_on}
{!!$listCustomers->链接(空,['class'=>'分页无页边顶部]])
显示{{$all}}结果中的1-10个

{{trans('messages.customerListPageSearchBox')}
@端部 @推送('脚本') Vue.组件(“客户网格”{ 模板:“#网格模板”, 道具:{ 客户:阵列, 列:数组, filterKey:字符串, 标题:对象 }, 数据:函数(){ var sortOrders={} this.columns.forEach(函数(键){ 排序器[键]=1 }) 返回{ 排序键:“”, 巫师:巫师 } }, 方法:{ 排序:功能(键){ this.sortKey=key this.sortOrders[key]=this.sortOrders[key]*-1 } } }) //引导演示 var demo=新的Vue({ el:“#应用程序”, 数据:{ searchQuery:“”, gridColumns:['erp_id'、'firstname'、'lastname'、'email'、'phone_1'、'status'、'created_on'], gridData:null, colTitles:{'erp_id':'@lang('messages.customerListPageTableCustomerNo'),'firstname':'@lang('messages.customerListPageTableFirstname'),'lastname':'@lang('messages.customerListPageTableLastname'),'email':'E-Mail','phone_1':'@lang('messages.customerListPageTablePhone'),'status':'status','status','created_on':'lang('messages.customerListPageTableAddedDate')} }, 已创建:函数(){ this.fetchData() }, 方法:{ fetchData:函数(){ var self=这个; $.get('/',函数(数据){ self.gridData=数据; }); } } }); @端推

请确保将值10更改为{$count}变量,以指定每页显示多少结果。请注意,它很可能是10,这是除最后一页之外的最大值。祝您好运。

有关如何在Vue中使用Laravel分页的示例:

控制器:

class UserController extends Controller
    {
        public function index()
        {
            return view('user.index', [
                'users' => User::all()->paginate(25),
            ]);
        }
    }
视图:


我试图按照代码进行操作,但我是vue的新手,这似乎有点让人困惑。您介意通过标记模板文件中的内容来编辑答案吗?