Search code examples
laravelvue.jsvuejs3laravel-9inertiajs

Laravel 9 and Vue 3 pagination


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.


Solution

  • 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!