First composition api with composables for issues

This tutorial is part of this mini project on Laravel vue spa. To see all the sections of this project click here

UPDATE: In Laravel 11, API route is not enabled by default. It needs to be enabled first before making api controllers with following artisan command.

php artisan install:api

After enabling api routes we can go on to create our controllers which are responsible to handle incoming requests from users.

Step 01: Creating IssueController for Api Endpoint inside Http/Controller/Api folder

php artisan make:controller Api/IssueController

Step 02: Adding index() method inside IssueController.php

// at the top 
// use App\Models\Issue;
public function index() {
   return Issue::all();
}
?>

Step 03: Creating api routes inside routes/api.php. Urls are prefixed with api when routes are being used from this file

Route::get('issues', [App\Http\Controllers\Api\IssueController::class, 'index']);
Step 04: Creating issues composable inside resources/js/composables/issues.js

import { ref } from 'vue'

export default function useIssues() {
    const issues = ref([])

    const getIssues = async () => {
        axios.get('/api/issues')
            .then(response => {
                issues.value = response.data;
            })
    }
    return { issues, getIssues }
}

Step 05: Creating vuejs component using issues composable and for loop inside Index.vue

<template>    
    <h1>Client Issues </h1>
<table class="table">
    <thead class="thead-dark">
      <tr>
        <th>ID</th>
        <th>Title</th>
        <th>Description</th>
        <th>Created</th>
      </tr>
    </thead>
    <tbody>
        <tr v-for="issue in issues">
            <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
                {{ issue.id }}
            </td>
            <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
                {{ issue.title }}
            </td>
            <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
                {{ issue.description }}
            </td>
            <td class="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-900">
                {{ issue.created_at }}
            </td>
        </tr>
    </tbody>
  </table>   
</template>

<script setup>

import { onMounted } from "vue";
import useIssues from "../../composables/issues";

const { issues, getIssues } = useIssues()
onMounted(() => {
    getIssues()
})

</script>

Related Posts


Seeding users and role_user data

Seeding clients and issues data

Adding client column in table

Storing issue in db table

Update issue

Showing user data and logout

Permission securing backend

Permission securing frontend