I'm trying to implement a pagination with Laravel 9 and Vue 3. But it's my first time that I'm doing this, and I don't know what to do.
First, I imported my library:
import { Link } from '@inertiajs/inertia-vue3';
Second, I have my component pagination in components
folder.
<script setup>
import { Link } from '@inertiajs/inertia-vue3';
defineProps({
data: {
type: Object,
default: () => ({}),
},
});
</script>
<template>
<div v-if="data.links.length > 3" class="flex justify-center mt-4 space-x-4">
<Link
v-for="(link, k) in data.links"
:key="k"
class="px-4 py-3 text-sm leading-4
bg-white rounded hover:bg-white
focus:text-indigo-500 hover:shadow"
:class="{'bg-indigo-400 text-white': link.active}"
:href="link.url"
v-html="link.label"
/>
</div>
</template>
Third, I imported my component into my other component:
<!-- ... -->
</table>
<pagination :data="preContracts" />
</template>
<script>
import usePrecontract from "../composables/precontract"
import { onMounted, defineComponent } from 'vue'
import pagination from "../components/pagination"
import { Head } from "@inertiajs/inertia-vue3";
import { Link } from "@inertiajs/inertia-vue3";
import { Inertia } from "@inertiajs/inertia";
export default defineComponent({
name: 'datatablePreContracts',
setup() {
const { preContracts, getPrecontract, deletePrecontract, queryForKeywords } = usePrecontract()
onMounted(getPrecontract)
function remove(id) {
deletePrecontract(id)
}
function searchId(action) {
let id = document.getElementsByClassName('id_search')[0].value
const params = [action, id];
queryForKeywords(params)
}
function searchName(action) {
let id = document.getElementsByClassName('name_search')[0].value
const params = [action, id];
queryForKeywords(params)
}
function searchPhone(action) {
let id = document.getElementsByClassName('phone_search')[0].value
const params = [action, id];
queryForKeywords(params)
}
function contract(action) {
alert("llego contract -> " + action);
}
function edit(action) {
alert("llego edit -> " + action);
}
function show(action) {
alert("llego show -> " + action);
}
function installation(action) {
alert("llego installation -> " + action);
}
return {
preContracts,
remove,
searchId,
searchName,
searchPhone,
contract,
edit,
show,
installation
}
}
})
</script>
In app.js
, I have this:
import pagination from './components/pagination';
const app = createApp({
components: {
datatableUsers,
datatableRoles,
datatablePermissions,
datatablePrecontract,
pagination
}
}).mount('#app')
But when my page is loaded, I have this in console:
Failed to resolve component: pagination If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. at
I don't know what I'm doing wrong. Can anyone help me?
UPDATE
With the help of @Angelina I resolved my problem in web browser console.
In app.js
I change this:
const app = createApp({
components: {
datatableUsers,
datatableRoles,
datatablePermissions,
datatablePrecontract,
}
})
app.component('pagination', pagination);
app.mount('#app')
Then I mount my component:
<pagination :data="preContracts.links" />
But now my pagination isn't shown.
UPDATE 2
This is my data in console:
{,…}
data: [{id: 10000, id_date: 0, id_commercial: 35, numerical_serie: 0, co_owner: 0, simplify: 0,…},…]
links: {first: "http://www.crm.local:8081/api/preContractApi?page=1",…}
meta: {current_page: 1, from: 1, last_page: 100,…}
Thanks for the help, and sorry for my bad English.
Sorry for this answer, but I believe that I found my problem... I have this in my controller:
return PreContractResource::collection(PreContract::with(['personalData','statusPre'])->paginate(10));
This returns a collection that contains all information from contracts and my pagination links.
But when I build my Axios petition, this is returned:
{,…}
data: [{id: 10000, id_date: 0, id_commercial: 35, numerical_serie: 0, co_owner: 0, simplify: 0,…},…]
links: {first: "http://www.crm.local:8081/api/preContractApi?page=1",…}
meta: {current_page: 1, from: 1, last_page: 100,…}
But when I try to access links, this is displayed in the console:
app.js:7203 [Vue warn]: Failed to resolve component: inertia-link If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.
at
<Pagination class="mt-6" links=undefined >
at
<DatatablePreContracts>
at
<App>
When I console.log
preContract.links
, undefined
is returned.
But in my petition it's... I don't know what I'm doing wrong. My table is filled perfectly with this pattern:
<template v-for="item of preContracts">
<tr>
<td>{{ item.id }}</td>
<td>{{ (item.personal_data) ? item.personal_data.name : '' }} {{ (item.personal_data) ? item.personal_data.surname1 : '' }} {{ (item.personal_data) ? item.personal_data.surname2 : '' }}</td>
<td>{{ (item.personal_data) ? item.personal_data.address : ''}}, {{ (item.personal_data) ? item.personal_data.population : ''}}</td>
<td>{{ (item.personal_data) ? item.personal_data.landline : ''}} </td>
<td>
<span class="text-light" :class="item.status_pre.class_span">
{{ (item) ? item.status_pre.name : 'null' }}
</span>
</td>
And all my data is ok...
My problem is that, for a strange reason, I can't get access to links...
UPDATE
I resolved my problem thanks to this thread.
Finally, I imported the pagination component into app.js to construct the global pagination.
app.component('pagination', require('./components/Pagination.vue').default);
Then I changed the pagination in my data table:
<pagination :pagination="pagination" :offset="7" @paginate="getPage(this.pagination.current_page)"></pagination>
I created a function in my script.
First, to do this, I added my composable function to my constant name:
const { preContracts, getPrecontract, deletePrecontract, queryForKeywords, getResults, **getItems** } = usePrecontract()
... and created function getPage(item)
:
function getPage(page){
getItems(page);
}
... and wrote this in my composable:
export default function usePrecontract() {
let preContracts = ref([])
let pagination = ref([])
const getPrecontract = async () => {
let response = await axios.get('/api/preContractApi')
preContracts.value = response.data.data
}
const deletePrecontract = (id) => axios.post(`/api/preContractApi/${id}`, {_method: 'delete'}).then(res => {
confirm("Are you sure you want to delete this item?")
location.reload();
}).catch(err => {
console.log(err);
});
const queryForKeywords = async (event) => {
const response = await axios.get('/api/preContractApi/show', {params: {'searchParams': event}})
preContracts.value = response.data.data
};
const getResults = async (page) => {
const response = axios.get('api/preContractApi?page=' + page)
preContracts.value = response.data
};
const getItems = async (page) => {
axios.get('/api/preContractApi?page=' + page)
.then(response => {
preContracts.value = response.data.data;
pagination.value = response.data.meta;
});
};
return {
preContracts,
getPrecontract,
deletePrecontract,
queryForKeywords,
getResults,
getItems
}
}
Thanks everyone in this thread for the help and @SAKIB for his response in another thread that helped me!