Courses

Vue Laravel 12 Starter Kit: CRUD Project

Delete Task and Shadcn Vue Toast Notification

Summary of this lesson:
- Adding delete functionality to the tasks table
- Using Shadcn Vue Button component with destructive variant
- Implementing confirmation before delete
- Adding success notifications with Sonner toast component

In this lesson, let's add the Delete button to our table.


Delete Button

Here's what we have in the Controller:

app/Http/Controllers/TaskController.php:

public function destroy(Task $task)
{
$task->delete();
 
return redirect()->route('tasks.index');
}

Since we have Route::resource() here, the Vue component should fire a DELETE request to the route /tasks/{ID}.

So, first, we define the function inside the Vue component.

resources/js/pages/Tasks/Index.vue:

import { Head } from '@inertiajs/vue3';
import { Head, router } from '@inertiajs/vue3';
 
// ...
 
defineProps<Props>();
 
const deleteTask = (id: number) => {
if (confirm('Are you sure you want to delete this task?')) {
router.delete(route('tasks.destroy', { id }));
}
};
 
// ...

Then, we need to add a Button to the table that calls the deleteTask() method.

The Shadcn Button component is already installed in the starter kit, so we don't need to run any npx commands. We just need to import it with button variants.

We add a new <TableCell> to our <TableRow>.

resources/js/pages/Tasks/Index.vue:

import { Button } from '@/components/ui/button';
 
// ...
 
<TableRow v-for="task in tasks" :key="task.id">
<TableCell>{{ task.name }}</TableCell>
<TableCell class="{{ task.is_completed ? 'text-green-600' : 'text-red-700'}}">
{{ task.is_completed ? 'Completed' : 'In Progress' }}
</TableCell>
<TableCell class="text-right">Button to edit/delete</TableCell>
<TableCell class="text-right">
<Button
variant="destructive"
@click="deleteTask(task.id)"
class="mr-2">Delete</Button>
</TableCell>
</TableRow>

Here's the visual result:

Now, see that variant="destructive"? To see what other button variants are available, look at this Shadcn documentation page.

Notice: In this course, we're adding custom Tailwind CSS classes to various components. I don't explicitly emphasize this, but it's pretty important: you must be good with Tailwind to customize the design to your needs.

If we click that Delete button, it will actually work: show a JS confirmation dialog and delete the task if confirmed.

For a better UX, we need to add the notification that the Delete action was successful.


Notifications with Toast/Sonner

To add a success alert/notification, we will use another Shadcn component called Sonner. They describe it as "opinionated toast component for Vue".

To install it, we run this command:

npx shadcn-vue@latest add sonner

As a result, we have a new folder resources/js/components/ui/sonner created.

Now, we can use it in our Vue component.

First, we show that notification from our Index.vue file.

resources/js/pages/Tasks/Index.vue:

import { toast } from 'vue-sonner';
 
// ...
 
const deleteTask = (id: number) => {
if (confirm('Are you sure you want to delete this task?')) {
router.delete(route('tasks.destroy', { id }));
toast.success('Task deleted successfully');
}
};

And then, we need to define where we show that notification.

Let's do it in the Header, in the top-right corner. In the AppHeaderLayout.vue, we need to import the <Toaster> component on top and use it in the <template> after the <AppContent>.

resources/js/layouts/app/AppHeaderLayout.vue:

import { AppShell } from '@/components/app-shell';
import { type BreadcrumbItem } from '@/types';
import { Toaster } from '@/components/ui/sonner'
 
// ...
 
<template>
<AppShell class="flex-col">
<AppHeader :breadcrumbs="breadcrumbs" />
<AppContent>
<slot />
</AppContent>
<Toaster position="top-right" />
</AppShell>
</template>

As a result, if we delete a task, we see this in the top-right corner:

Success!

Here is the GitHub commit for this lesson.


In the next lesson, we will build the Create form of the CRUD.

Previous: Shadcn Vue Table: Tasks List
avatar

the GitHub link is not working

avatar

Sorry, sometimes I forget to put repositories public. Fixed now!

avatar
You can use Markdown
avatar
You can use Markdown