如何使用 Laravel rest api 在 vue-tables-2 上添加分页?

Posted

技术标签:

【中文标题】如何使用 Laravel rest api 在 vue-tables-2 上添加分页?【英文标题】:How to add pagination on vue-tables-2 using Laravel rest api? 【发布时间】:2019-05-31 07:16:02 【问题描述】:

我应该怎么做才能从 Laravel 端点对 Vue 服务器表启用分页?

我的组件:

<template>
    <div>
        <v-server-table :columns="columns" url="/object/find" :options="options">
        </v-server-table>
    </div>
</template>
<script>
export default 
data () 
      return 
        columns: ['name', 'type', 'created_by', 'created_at'],
        options: 
          perPage: 5,
          perPageValues: [5, 10, 15, 25, 50, 100],
          pagination: chunk: 5,
          dateColumns: ['created_at'],
          dateFormat: 'DD-MM-YYYY HH:mm',
          datepickerOptions: 
            showDropdowns: true,
            autoUpdateInput: true,
          
          filterable: ['name', 'type','created_by', 'created_at'],
          sortable: ['name', 'type', 'created_by', 'created_at'],
          requestAdapter (data) 
            return 
              sort: data.orderBy ? data.orderBy : 'name',
              direction: data.ascending ? 'asc' : 'desc',
              limit: data.limit ? data.limit : 5,
              page: data.page,
              name: data.query.name,
              created_by: data.query.created_by,
              type: data.query.type,
              created_at: data.query.created_at
            
          ,
          responseAdapter (data) 
            return 
              data,
              count: data.length
            
          ,
        
      
    ,
 
</script>

控制器:

public function findObjects(Request $request)
    
        $objects = Objects::withTrashed();
        $sort = $request->get('sort');
        $direction = $request->get('direction');
        $name = $request->get('name');
        $created_by = $request->get('created_by');
        $type = $request->get('type');
        $limit = (int)$request->get('limit');
        $page = (int)$request->get('page');
        $created_at = $request->get('created_at');
        if ($sort !== null && $direction !== null) 
            $objects->orderBy($sort, $direction);
        
        if ($name !== null) 
            $objects->where('name', 'like', '%' . $name . '%');
        
        if ($created_by !== null) 
            $objects->where('created_by', 'like', '%' . $created_by . '%');
        
        if ($type !== null) 
            $objects->where('type', 'like', '%' . $type . '%');
        
        if ($created_at !== null) 
            $date_range = json_decode($created_at);
            $objects->whereBetween('created_at', [Carbon::parse($date_range->start), Carbon::parse($date_range->end)]);
        

         return $objects->get();
    

所有过滤器都可以正常工作。当我使用 LIMITTAKEPAGINATE 时,它将返回 5 个项目,并且分页链接在组件中不起作用。 我应该在我的控制器和组件中做什么以在页面上显示例如 5 个项目?

【问题讨论】:

您查看过文档吗? github.com/matfish2/vue-tables-2#options 向下滚动到分页选项。 你能更新你的后端代码吗? 我将代码上传到我的问题中。 @mare96 我更新了我的答案。尝试使用我在答案中添加的控制器代码并告诉我 【参考方案1】:

请仔细阅读文档here

您需要返回一个带有两个属性的 JSON 对象:

data : array - 具有相同键的行对象数组。

count: number - 限制前的总数。

例如,您的 JSON 应如下所示:

[ 
    "data": [
        
          "name": "Name1", 
          "created_at": "01-01-2019 00:00:01, 
          "updated_at": "02-01-2019 10:12:13",
          "pushed_at" : "01-01-2019 00:00:05"
       ,
        
          "name": "Name2", 
          "created_at": "01-01-2019 00:00:01, 
          "updated_at": "02-01-2019 10:12:13",
          "pushed_at" : "01-01-2019 00:00:05"
       , 
        
          "name": "Name3", 
          "created_at": "01-01-2019 00:00:01, 
          "updated_at": "02-01-2019 10:12:13",
          "pushed_at" : "01-01-2019 00:00:05"
       
    ],
    "count":100
]

在您的控制器中,您不会返回 vue-table-2 分页的总行数。在您的回复中添加计数将解决您的问题

使用以下代码更改您的控制器代码:

public function findObjects(Request $request)

    $objects    = Objects::withTrashed();
    $sort       = $request->get('sort');
    $direction  = $request->get('direction');
    $name       = $request->get('name');
    $created_by = $request->get('created_by');
    $type       = $request->get('type');
    $limit      = (int)$request->get('limit');
    $page       = (int)$request->get('page');
    $created_at = $request->get('created_at');
    if ($sort !== null && $direction !== null) 
        $objects->orderBy($sort, $direction);
    
    if ($name !== null) 
        $objects->where('name', 'like', '%' . $name . '%');
    
    if ($created_by !== null) 
        $objects->where('created_by', 'like', '%' . $created_by . '%');
    
    if ($type !== null) 
        $objects->where('type', 'like', '%' . $type . '%');
    
    if ($created_at !== null) 
        $date_range = json_decode($created_at);
        $objects->whereBetween('created_at', [Carbon::parse($date_range->start), Carbon::parse($date_range->end)]);
    

    $count = $objects->count();

    $objects->offset($limit * ($page - 1))->limit($limit);

    $data = $objects->get()->toArray();

    return response()->json([
        'data'  => $data,
        'count' => $count
    ]);

并像这样更改您的 vuejs 代码

<template>
<div>
    <v-server-table :columns="columns" url="/object/find" :options="options">
    </v-server-table>
</div>
</template>
<script>
export default 
data () 
      return 
        columns: ['name', 'type', 'created_by', 'created_at'],
        options: 
          perPage: 5,
          perPageValues: [5, 10, 15, 25, 50, 100],
          pagination: chunk: 5,
          dateColumns: ['created_at'],
          dateFormat: 'DD-MM-YYYY HH:mm',
          datepickerOptions: 
            showDropdowns: true,
            autoUpdateInput: true,
          
          filterable: ['name', 'type','created_by', 'created_at'],
          sortable: ['name', 'type', 'created_by', 'created_at'],
          requestAdapter (data) 
            return 
              sort: data.orderBy ? data.orderBy : 'name',
              direction: data.ascending ? 'asc' : 'desc',
              limit: data.limit ? data.limit : 5,
              page: data.page,
              name: data.query.name,
              created_by: data.query.created_by,
              type: data.query.type,
              created_at: data.query.created_at
            
          
        
      
    ,
 
</script>

【讨论】:

我这几天一直在寻找服务器端的解释,这个解释是我能找到的最好的!谢谢【参考方案2】:

为了启用分页,您需要在 SQL 语句中完成。如果您使用 SQL Server,请使用 OFFSET/FETCH。如果您使用 mysql,请使用 LIMIT/OFFSET。使用此链接作为参考:

What is the best way to paginate results in SQL Server

【讨论】:

不知道为什么你被否决了,你确实是对的。事物的后端也需要适应接收来自服务器表的请求(搜索文本、页面大小、页码等)并做出相应的响应。这通常意味着使用限制/偏移量的 SQL 语句在数据库中执行。我不知道 laravel 如何与服务器表一起工作,但这里似乎有一个服务器端实现:npmjs.com/package/vue-tables-2#implementations

以上是关于如何使用 Laravel rest api 在 vue-tables-2 上添加分页?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 5 中验证 RESTful API?

如何在 laravel 中使用社交名流和护照创建 REST API

如何在 Laravel Jetstream 上使用 REST API 管理用户

如何使用 Laravel 5.3 创建 REST 完整 Web 服务的 Api

如何使用phpunit在具有动态URI的laravel中测试REST api

如何在 Laravel 中为 REST API 创建身份验证