skip to Main Content

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.

3

Answers


  1. Chosen as BEST ANSWER

    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!


  2. Here you might find the answer.

    Registering components in the root component’s components option doesn’t make them global. Doing that just makes them available to the root component itself, not its children.

    To register components globally, use app.component in your top-level code.

    app.js

    import { createApp } from 'vue';
    import App from './App.vue';
    import MyGlobalComponent from './components/MyGlobalComponent.vue';
    const app = createApp(App);
    app.component('MyGlobalComponent', MyGlobalComponent); ✅
    const mountedApp = app.mount('#app');
    
    Login or Signup to reply.
  3. You have a ready solution for this, why are you trying to reinvent the wheel? Installation is really simple and well documented.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search