4. Laravel 8 con auth ui y VUE.js 3 - Index, eliminar

Más
1 año 5 meses antes - 1 año 5 meses antes #44 por luispindola
Este tema es continuación de:
3. Laravel 8 con auth ui y VUE.js 3 - Formularios

Indicaciones para completar el CRUD con Vue.js 3. agregando la funcionalidades de listar registros (index) y eliminar.

1. en el Controlador:
Controller/Api/LibrosController.php se deben crear las funciones para la vista de listado (index), destroy, show y update para modificad la base de datos
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\LibroRequest;
use App\Http\Resources\LibroResource;
use App\Models\Libro;
use Illuminate\Http\Request;


class LibrosController extends Controller
{
    //
    public function storeLibro (LibroRequest $request)
    {
        //Guardar registro en la base de datos
        $libro = Libro::create($request->validated());
        return new LibroResource($libro);
    }


    
    public function index()
    {
        //Listar Libros:
        
        $libros = Libro::get();
        
        return LibroResource::collection($libros);
    }


    public function destroyLibro($id)
    {
        //Eliminar registro
        $libro = Libro::find($id);
        $libro->delete();
        
        return response()->noContent();
    }

    public function showLibro($id)
    {
        //Mostrar registro
        $libro = Libro::find($id);
        return new LibroResource($libro);
    }

    public function updateLibro(LibroRequest $request, $id)
    {
        //Editar Libro
        $libro = Libro::find($id);
        $libro->update($request->validated());

        return new LibroResource($libro);
    }
}

2. Se crean las rutas para acceder a las funciones del controlador en el archivo:
routes/api.php
<?php

use App\Http\Controllers\Api\LibrosController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});



Route::post('libros/store', [LibrosController::class, 'storeLibro']);
Route::get('libros', [LibrosController::class, 'index']);
Route::delete('libros/{id}' ,[LibrosController::class, 'destroyLibro']);
Route::get('libros/{id}', [LibrosController::class, 'showLibro']);
Route::post('libros/{id}/update', [LibrosController::class, 'updateLibro']);

3. Se crean las funciones javascript para comunicarse con el controlador
resources/js/libro.js
import { ref } from 'vue'
import { useRouter } from 'vue-router'

export default function useLibros(){
	const errors = ref('')
	const router = useRouter()
	const libros = ref([])
	const libro = ref([])

	const storeLibro = async (data) => {
		console.log("Funcion para enviar data via  post por axios")

		errors.value = ''
		try{
			await axios.post('/api/libros/store',data) 
			await router.push({name: 'holamundo'})
		} catch(e){			
			if(e.response.status === 422){
				errors.value = e.response.data.errors
			}
		}
	} 

	const getLibros = async() => {
		console.log("Funcion para listar vista index")

        axios.get('/api/libros')
        .then(response => {
            libros.value = response.data;
        })
    }

    const destroyLibro = async(id)	=>	{
    	console.log("Funcion para borrar libro " + id)
    	await axios.delete('/api/libros/' + id)
    }

    const getLibro = async(id)	=>	{
    	console.log("Funcion mostrar vista de editar")
    	let response = await axios.get('/api/libros/'+ id)
    	libro.value = response.data.data
    }

    const updateLibro = async (id)	=>	{
    	console.log("Funcion para enviar data via  post para editar por axios")
    	errors.value = ''
    	try{
    		await axios.post('/api/libros/' + id + '/update', libro.value)
    		await router.push({name: 'holamundo'})
    	}catch(e){			
			if(e.response.status === 422){
				errors.value = e.response.data.errors
			}
		}
    }

	return {
		libros,
		libro,
		errors,
		storeLibro,
		getLibros,
		destroyLibro,
		getLibro,
		updateLibro,
	}
}

4. Modificamos el archivo HolaMundo.vue para que sea donde se muestre el listado de la funcion index:
resources/js/components/HolaMundo.vue
<template>
	<div class="card">
    	<div class="card-header">{{ saludo }}</div>
		<div class="card-body">
			
			<table class="table table-striped table-hover">
		         <thead>
		            <tr>
		               <th scope="col">#</th>
		               <th scope="col">Titulo</th>
		               <th scope="col">Descripción</th>
		               <th scope="col">Acciones</th>
		            </tr>
		         </thead>
		         <tbody>
		            <template v-for="item in libros.data" :key="item.id">
		             <tr>
		               <th scope="row">{{ item.id }}</th>
		                <td>{{ item.titulo }}</td>
		                <td>{{ item.descripcion }}</td>
		                <td>
		                  <button type="button" @click="deleteLibro(item.id)" class="btn btn-sm btn-danger">Eliminar</button>
		                     
		                  <router-link :to="{name: 'editalibro', params: {id: item.id} }" class="btn btn-sm btn-primary">Editar </router-link>
		                </td>
		             </tr>
		            </template>   
		         </tbody>
		   </table>


		</div>
	</div>

</template>

<script>
import useLibros from "../libros.js";
import { onMounted } from "vue";

export default {
	setup(){
		const saludo = "Hola Vue.js 3"

		const {libros, getLibros, destroyLibro} =  useLibros()

		onMounted(getLibros)

		const deleteLibro = async(id)	=>	{
			if(!window.confirm("Estas seguro?")){
				return
			}
			await destroyLibro(id)
			await getLibros()
		}

		return {
			saludo,
			libros,
			getLibros,
			deleteLibro
		}
	}
}
</script>

5. Creamos la ruta de vue para la pantalla de edicion de registros en el archivo:
resources/js/router/index.js
import { createRouter, createWebHistory } from "vue-router";

//const Principal = () => import("../components/Principal.vue");
const HolaMundo = () => import("../components/HolaMundo.vue");
const CreaLibro = () => import("../components/CreaLibro.vue");
const EditaLibro = () => import("../components/EditaLibro.vue");

const routes = [
	
	{
		path: '/home',
		name: 'holamundo',
		component: HolaMundo
	},
	{
		path: '/crealibro',
		name: 'crealibro',
		component: CreaLibro
	},
	{
		path: '/editalibro/:id/edit',
		name: 'editalibro',
		component: EditaLibro, 
		props: true
	}
]

export const router = createRouter({
	history: createWebHistory(),
	routes
})

6.- Creamos el componente para editar registros:
resources/js/components/EditaLibro.vue
<template>
	<div class="card">
    	        <div class="card-header">{{ tituloform }}</div>
		<div class="card-body">
			<div id="formulario-persona">

		 	<div v-if="errors"> 
        <div v-for="(v, k) in errors" :key="k">
          <p class="text-danger" v-for="error in v" :key="error">  
              {{ error }}
          </p>
        </div>
    	</div>

			<form @submit.prevent="onSubmit">
					<div class="form-group">
		              <label>Titulo</label>
		              <input type="text" v-model="libro.titulo" class="form-control" />
		            </div>
		            <div class="form-group">
		              <label>Descripción</label>
		              <input type="text" v-model="libro.descripcion" class="form-control" />
		            </div>


		            <div class="row">
			          <div class="col-md-4">
			            <div class="form-group">
			              <button type="submit" class="btn btn-primary" >Añadir libro</button>

			              
			            </div>
			          </div>
			        </div>
				</form>

			</div>
		</div>
	</div>
</template>

<script>
import { reactive } from 'vue';
import { ref } from 'vue';
import { onMounted }	from 'vue';
import useLibros from "../libros.js";

export default {
	props: {
		id: {
			required: true,
			type: String
		}

	},

	setup(props) {
		

		//const form = reactive({
		//	titulo: '',
		//	descripcion: ''
		//})

		const tituloform = "Titulo de formulario -  Editar"

		const {errors, libro, getLibro, updateLibro} = useLibros()

		onMounted(getLibro(props.id))



		const onSubmit = async()=> {
			console.log("Recibida en funcion submit para editar ("+libro.titulo+")")
			await updateLibro(props.id)
		}

		return {
			libro,
			tituloform,
			onSubmit,
			errors
		}
	}
}	
</script>
<style scoped>
  form {
    margin-bottom: 2rem;
  }
</style>

Al final tenemos un CRUD basico que se vera asi:



En el siguiente link se encuentra el proyecto completo hasta este punto--->

Parte del mensaje está oculto para usuarios no registrados. Por favor inicie sesión o regístrese para poder verlo.
Adjuntos:
Última Edición: 1 año 5 meses antes por luispindola.

Por favor, Identificarse o Crear cuenta para unirse a la conversación.

Tiempo de carga de la página: 0.098 segundos