Skip to content

Instantly share code, notes, and snippets.

@kuc-arc-f
Last active Jun 4, 2022
Embed
What would you like to do?
Vue 2 typescript + laravel 9, paginate sample
{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"require": {
"php": "^8.0.2",
"guzzlehttp/guzzle": "^7.2",
"laravel/framework": "^9.11",
"laravel/sanctum": "^2.14.1",
"laravel/tinker": "^2.7",
"laravel/ui": "^3.4"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",
"laravel/sail": "^1.0.1",
"mockery/mockery": "^1.4.4",
"nunomaduro/collision": "^6.1",
"phpunit/phpunit": "^9.5.10",
"spatie/laravel-ignition": "^1.0"
},
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/"
}
},
"scripts": {
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-update-cmd": [
"@php artisan vendor:publish --tag=laravel-assets --ansi --force"
],
"post-root-package-install": [
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
],
"post-create-project-cmd": [
"@php artisan key:generate --ansi"
]
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"@popperjs/core": "^2.10.2",
"@types/node": "^17.0.38",
"@types/webpack-env": "^1.17.0",
"@vue/compiler-sfc": "^3.2.36",
"axios": "^0.25",
"bootstrap": "^5.1.3",
"laravel-mix": "^6.0.6",
"lodash": "^4.17.19",
"postcss": "^8.1.14",
"resolve-url-loader": "^3.1.2",
"sass": "^1.32.11",
"sass-loader": "^11.0.1",
"ts-loader": "^9.2.6",
"typescript": "^4.7.2",
"vue": "^2.6.12",
"vue-loader": "^15.9.8",
"vue-template-compiler": "^2.6.12"
},
"dependencies": {
"vue-router": "^3.1.3"
}
}
<template>
<div class="">
<!--
<h3>PaginateChild</h3>
-->
<nav class="my-2">
<ul class="pagination">
<li class="page-item">
<a @click="first" class="page-link" href="#">&laquo;</a>
</li>
<li class="page-item">
<a @click="prev" class="page-link" href="#">&lt;</a>
</li>
<li v-for="i in displayPageRange"
class="page-item"
:class="{active: i-1 === childCurrentPage}">
<a @click="pageSelect(i)" class="page-link" href="#">{{ i }}</a>
</li>
<li class="page-item">
<a @click="next" class="page-link" href="#">&gt;</a>
</li>
<li class="page-item">
<a @click="last" class="page-link" href="#">&raquo;</a>
</li>
</ul>
</nav>
</div>
</template>
<!-- -->
<style>
</style>
<!-- -->
<script lang="ts">
import Vue from 'vue';
//
interface DataType {
child_num: number,
childCurrentPage: number,
pages: number,
}
//
export default Vue.extend({
props: {
currentPage: {type: Number, default: 0},
size: {type: Number, default: 0},
pageRange: {type: Number, default: 0},
items: {type: Array, default: []},
},
data(): DataType {
return {
child_num: 120,
childCurrentPage: 0,
pages: 0,
};
},
created () {
console.log( "currentPage=", this.currentPage)
console.log( "size=", this.size )
console.log( "pageRange=", this.pageRange )
// console.log( "items=", this.items)
},
computed: {
/**
* ページネーションで表示するページ番号の範囲を取得する
*/
displayPageRange () : any[]{
const half = Math.ceil(this.pageRange / 2);
let start, end;
this.pages = this.pageCount()
if (this.pages < this.pageRange) {
start = 1;
end = this.pages;
} else if (this.currentPage < half) {
start = 1;
end = start + this.pageRange - 1;
} else if (this.pages - half < this.currentPage) {
end = this.pages;
start = end - this.pageRange + 1;
} else {
start = this.currentPage - half + 1;
end = this.currentPage + half;
}
let indexes = [];
for (let i: number = start; i <= end; i++) {
//@ts-ignore
indexes.push(i);
}
return indexes;
},
},
methods: {
/**
* ページ数を取得する
*/
pageCount () : number {
return Math.ceil(this.items.length / this.size);
},
first () {
// console.log("first");
this.childCurrentPage = 0;
this.selectHandler();
},
prev () {
if (0 < this.currentPage) {
this.childCurrentPage--;
this.selectHandler();
}
},
next () {
this.pages = this.pageCount()
if (this.currentPage < this.pages - 1) {
this.childCurrentPage++;
this.selectHandler();
}
},
last () {
this.pages = this.pageCount()
this.childCurrentPage = this.pages - 1;
this.selectHandler();
},
pageSelect (index: number) {
this.childCurrentPage = index - 1;
this.selectHandler();
},
selectHandler () {
this.$emit("recvCurrentPage", this.childCurrentPage);
},
},
})
</script>
<template>
<div class="container">
<h3>PaginateParent</h3>
<!--
<p>parent_num: {{ currentPage }}</p>
-->
<ul class="list-group">
<li v-for="item in displayItems" class="list-group-item">
{{ item.text }}
</li>
</ul>
<hr />
<PaginateBox
:currentPage="currentPage"
:size = "size"
:pageRange = "pageRange"
:items="items"
@recvCurrentPage='reflectNum'>
</PaginateBox>
</div>
</template>
<!-- -->
<style>
</style>
<!-- -->
<script lang="ts">
import Vue from 'vue';
import PaginateBox from './PaginateBox.vue';
type DataType = {
currentPage: number
size: number
pageRange: number
items: any[],
}
export default Vue.extend({
components: { PaginateBox },
data(): DataType {
return {
currentPage: 0, // 現在のページ番号
size: 10, // 1ページに表示するアイテムの上限
pageRange: 8, // ページネーションに表示するページ数の上限
items: [], // 表示するアイテムリスト
}
},
created () {
try{
//console.log("created")
this.items = [...Array(200)].map((_, i) => {
return {
text: `TestItem: ${i}`
};
});
} catch (e) {
console.error(e);
}
// console.log( "items=", this.items )
},
computed: {
/**
* 現在のページで表示するアイテムリストを取得する
*/
displayItems () : any[] {
const head = this.currentPage * this.size;
return this.items.slice(head, head + this.size);
},
},
methods: {
reflectNum(value: any) : void {
this.currentPage = value;
console.log("reflectNum.parent_num", this.currentPage);
}
}
})
</script>
{
"compilerOptions": {
"module": "es2015",
"target": "es5",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"typeRoots": ["./resources/js/@types"],
"lib": [
"es2016", "dom", "dom.iterable", "scripthost"
],
"noImplicitAny": false,
},
"include": [
"resources/js/**/*.ts",
"resources/js/**/*.tsx",
"resources/js/**/*.vue"
],
"exclude": ["node_modules"]
}
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.ts('resources/js/app.ts', 'public/js')
.vue()
.sass('resources/sass/app.scss', 'public/css');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment