Vue.js+Laavel을 사용하여 페이지 스타일을 구현하는 노트
컨디션
페이지 스타일
페이지 스타일은 목록을 표시할 때 숫자를 여러 페이지로 나누는 것을 말한다.
SP A의 페이지 문자 예
좀 복잡하니까 그림으로 정리해 주세요.
먼저 페이지의 페이지 번호(①)를 클릭합니다.
앞에서 예를 들어 페이지 번호 2를 눌렀을 때
?page=2
와 같이 조회 파라미터를 추가하여 요청을 보낸다(②).API는 쿼리 매개변수에 따라 OFFSET 문 또는 LIMIT 문을 사용하여 DB에서 해당 데이터를 가져옵니다(③, ④).
마지막으로 얻은 데이터에 따라 화면을 업데이트한다(⑤).
API 구현
Laavel의 API 리소스를 사용하여 수행할 수 있습니다.페이지가 나뉘어진 데이터를 API 리소스로 보내면 페이지 스타일은 필요한 정보(총 페이지 수 및 현재 페이지 번호 등)를 제공합니다.
우선, 컨트롤러는 모델을 사용하여 데이터를 얻어
pagenate
방법으로 붙인다.그런 다음 붙여넣은 데이터를 API 리소스에 전달하여 성형합니다.backend/app/Http/Controllers/TaskController.php
class TaskController extends Controller
{
public function __construct(
private Task $taskModel
) {
}
public function index()
{
return TaskResource::collection($this->taskModel->with('status')->paginate(10));
}
}
API 리소스는 작업 정보 외에도 관계를 사용하여 작업 상태 이름을 가져옵니다.backend/app/Http/Resources/TaskResource.php
class TaskResource extends JsonResource
{
public function toArray($request)
{
/** @var \App\Models\Task */
$task = $this->resource;
assert($task->relationLoaded('status')); // N+1が起きないようにロードされていることを確認
return [
'id' => $task->id,
'name' => $task->name,
'description' => $task->description,
'status' => $task->status->name,
];
}
}
페이지 나누기 데이터(페이지 이름 지정자)를 API 리소스에 제출하면 다음과 같은 정보가 추가됩니다.키
디테일
links
첫 페이지, 마지막 페이지, 취득한 페이지의 앞뒤 페이지의 URL입니다.
meta
현재 페이지 번호, 마지막 페이지 번호, 페이지 수, 총 수량 등.
meta.links
페이지 스타일을 표시하는 링크 집합입니다.후퇴 링크, 현재 페이지의 앞뒤 3페이지, 시작과 마지막 2페이지의 링크를 포함한다.
예를 들어 총 수량 100건, 각 페이지 3건, 페이지 번호 10이 API를 실행할 때 다음과 같다.
응답 예제
$ curl 'localhost:8000/api/tasks?page=10' | jq .
{
"data": [
{
"id": 28,
"name": "todo28",
"description": "28個目",
"status": "OPEN"
},
{
"id": 29,
"name": "todo29",
"description": "29個目",
"status": "OPEN"
},
{
"id": 30,
"name": "todo30",
"description": "30個目",
"status": "CLOSED"
}
],
"links": {
"first": "http://localhost:8000/api/tasks?page=1",
"last": "http://localhost:8000/api/tasks?page=34",
"prev": "http://localhost:8000/api/tasks?page=9",
"next": "http://localhost:8000/api/tasks?page=11"
},
"meta": {
"current_page": 10,
"from": 28,
"last_page": 34,
"links": [
{
"url": "http://localhost:8000/api/tasks?page=9",
"label": "« Previous",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=1",
"label": "1",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=2",
"label": "2",
"active": false
},
{
"url": null,
"label": "...",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=7",
"label": "7",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=8",
"label": "8",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=9",
"label": "9",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=10",
"label": "10",
"active": true
},
{
"url": "http://localhost:8000/api/tasks?page=11",
"label": "11",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=12",
"label": "12",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=13",
"label": "13",
"active": false
},
{
"url": null,
"label": "...",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=33",
"label": "33",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=34",
"label": "34",
"active": false
},
{
"url": "http://localhost:8000/api/tasks?page=11",
"label": "Next »",
"active": false
}
],
"path": "http://localhost:8000/api/tasks",
"per_page": 3,
"to": 30,
"total": 100
}
}
Laavel의 라우터는 컨트롤러 작업을 수행한 후 작업의 반환값을 성형한 후 커널로 돌아갑니다.동작의 반환값을 성형할 때 반환값toResponse
을 호출하는 방법(반환값Illuminate\Contracts\Support\Responsable
이 인터페이스를 실시할 때.API 리소스의 상속자인 Json Resource 클래스가 여기에 적용됩니다.자원 수집
toResponse
방법에는 페이지 명명기 클래스를 건네주는 경우의 처리가 적혀 있습니다.이쪽을 쫓아가면 상술한 정보를 추가한 처리를 확인할 수 있습니다.ResourceCollection.php
public function toResponse($request)
{
if ($this->resource instanceof AbstractPaginator || $this->resource instanceof AbstractCursorPaginator) {
return $this->preparePaginatedResponse($request);
}
return parent::toResponse($request);
}
참조: Illuminate\Http\Resources\Json\ResourceCollection | Laravel API프런트엔드 설치
API 리소스의
meta.links
를 사용하여 페이지 스타일의 페이지 번호를 만들었습니다.페이지 번호를 클릭하면 API 끝점의 질의 문자열에서 페이지 번호를 가져오고 데이터를 다시 가져옵니다.
frontend/pages/index.vue
<script setup>
const page = ref(1)
const { data: taskPaginator, refresh } = await useFetch(() => `/api/tasks?page=${page.value}`, {
baseURL: 'http://localhost:8000',
})
const onClickLink = (url) => {
page.value = new URL(url).searchParams.get('page')
refresh()
}
</script>
<template>
<div>
<!-- 一覧の表示 -->
<h2>タスク一覧</h2>
<table>
<thead>
<tr>
<th>ID</th>
<th>タスク名</th>
<th>説明名</th>
<th>ステータス</th>
</tr>
</thead>
<tbody>
<tr v-for="task in taskPaginator.data">
<td>{{ task.id }}</td>
<td>{{ task.name }}</td>
<td>{{ task.description }}</td>
<td>{{ task.status }}</td>
</tr>
</tbody>
</table>
<!-- ページネーションの表示 -->
<div class="pagination">
<template v-for="link in taskPaginator.meta.links">
<button
:disabled="link.url === null"
class="pagination-link"
:class="{
'pagination-link-enabled': link.url !== null,
'pagination-link-active': link.active,
}"
@click="onClickLink(link.url)"
>
{{ link.label }}
</button>
</template>
</div>
</div>
</template>
페이지 레이아웃 구성 요소
다른 페이지에서도 페이지 하이픈을 사용할 수 있도록 구성 요소를 만들어 보십시오.
어셈블리 면:
frontend/components/custom/Pagination.vue
<script lang="ts" setup>
type PaginationLink = {
url: string | null
label: string
active: boolean
}
type Props = {
links: PaginationLink[]
onClickLink: (url: string) => void
}
const { links, onClickLink } = defineProps<Props>()
</script>
<template>
<div class="pagination">
<template v-for="link in links">
<button
:disabled="link.url === null"
class="pagination-link"
:class="{
'pagination-link-enabled': link.url !== null,
'pagination-link-active': link.active,
}"
@click="onClickLink(link.url)"
>
{{ link.label }}
</button>
</template>
</div>
</template>
호출자:<custom-pagination
:links="taskPaginator.meta.links"
:on-click-link="onClickLink"
class="task-pagination"
/>
잘 나온다.총결산
Reference
이 문제에 관하여(Vue.js+Laavel을 사용하여 페이지 스타일을 구현하는 노트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/tekihei2317/articles/7bb54c6d5a340e텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)