Cree una aplicación de una sola página con Laravel y Vue

Con su sintaxis limpia y expresividad, entre muchas otras cualidades, Laravel es uno de los frameworks PHP más populares utilizados por los desarrolladores.

Antes de que apareciera Laravel UI, una de sus características principales era admitir Vue.js de forma predeterminada desde Laravel v5.3 a v6. Vue es un marco de interfaz de usuario de JavaScript moderno para crear interfaces de usuario.

¿Por qué Laravel y Vue combinan tan bien?

Estas son algunas de las ventajas clave de usar Laravel con Vue para crear un flujo de trabajo completo para sus proyectos:

  • El código fuente se fusiona en un proyecto en lugar de tener proyectos separados para el backend y el frontend.

  • Instalación y configuración sencillas

  • Una única implementación puede manejar ambos marcos.

¿Qué es un balneario? (aplicación de una sola página)

¿Cómo ingresa una aplicación de una sola página (SPA para abreviar) a la configuración del BIOS en Windows 10? Tutorial gráfico detallado de ocho pasos Los nuevos datos se cargan dinámicamente desde el servidor web a la página web sin actualizar toda la página.

Ejemplos de sitios populares que utilizan SPA incluyen gmail.com y youtube.com; en otras palabras, los SPA son en gran medida omnipresentes. La mayoría de los paneles de administración que probablemente utilice a diario se crearon utilizando SPA.

Beneficios del Spa:

  • La experiencia del usuario es más flexible

  • datos de caché en el navegador

  • tiempo de carga rápido

Desventajas del SPA:

  • Puede dañar el SEO (optimización de motores de búsqueda)

  • posibles problemas de seguridad

  • Consume muchos recursos del navegador.

configuración del proyecto

Esta publicación demostrará cómo desarrollar una aplicación de tareas pendientes que permita a los usuarios registrarse para obtener una cuenta y agregar tareas.

En este tutorial se utiliza Laravel 9, el cual requiere PHP 8.1 y Vue 3; también necesitamos PHP y NGINX instalados.

Comencemos con el siguiente comando:

compositor crear-proyecto --prefer-dist laravel/laravel laravel-vue-demo

A continuación, instalaremos las dependencias de JavaScript.

instalación npm

Antes de que podamos agregar Vue a nuestro proyecto, debemos instalar algunos paquetes.

Además, se debe instalar plugin-vue ¿ Cómo pueden los teléfonos móviles Xiaomi comprobar si el hardware está roto? ¿Cómo detectar el teléfono móvil Xiaomi por sí solo? Porque Laravel 9 viene con Vite en lugar de webpack-mix, que es el paquete de Laravel para JavaScript. Ahora hagamos esto:

npm instala vue@siguiente vue-loader@siguiente @vitejs/plugin-vue

Abra el archivo llamado y agregue a la configuración: vite.config.js``vue()

importar {defineConfig} desde 'vite'; 
importar laravel desde 'laravel-vite-plugin'; 
importar vue desde '@vitejs/plugin-vue' 
exportar
default defineConfig({ 
    complementos: [ 
        vue(), 
        laravel([ 
            'resources/css/app.css', 
            'resources/js/app.js', 
        ]), 
    ], 
});

Edite el archivo y el fragmento de código para el arranque de la aplicación Vue 3: app.js

require('./bootstrap'); 
​importar
{createApp} desde 'vue' 
​importar
aplicación desde './App.vue' 
​createApp
(App).mount("#app")

Cree un archivo llamado y agregue el siguiente contenido: App.vue

<template> 
  <h1> Hola, Vuejs con Laravel </h1> 
</template> 
<script> 
export default { 
  setup() { 
   ​}
 
} 
</script>

Finalmente, abra el archivo ubicado en la carpeta y agregue el siguiente contenido: bienvenido.blade.php ``resources/views

<!DOCTYPE html> 
<html> 
<head> 
 .... 
        @vite('resources/css/app.css') 
</head> 
<body> 
  <div id="app"></div> 
  @vite( 'recursos/js/app.js') 
</body> 
</html>

Para obtener una vista previa de nuestra aplicación, necesitamos iniciar nuestra aplicación Vue y el servidor Laravel en dos terminales/líneas de comando diferentes :

npm run dev 
php

servicio artesanal

Para construir nuestra aplicación de tareas pendientes, necesitamos crear algunos archivos más. Vue creará varias páginas, principalmente:

  • página de inicio de sesión

  • pagina de registro

  • pagina de inicio

Para comunicarnos con los puntos finales de Laravel, necesitamos instalar Axios:

npm instala axios

enrutamiento de vista

Hay varias estrategias de enrutamiento disponibles en Vue usando el paquete vue-router ; estas estrategias también se conocen como patrones históricos.

Cuando un usuario solicita una ruta como esta (que devolverá un error 404 cuando se actualice la página), podemos confiar en Laravel para detectar cualquier ruta alternativa y luego entregar el archivo Blade que contiene nuestra aplicación. http://localhost:8000/casa

Por tanto, usaremos el modo HTML5:

Ruta::get('/{vue_capture?}', function() { 
    return view('bienvenido'); 
})->where('vue_capture', '[\/\w\.-]*'); 
importar {createRouter, createWebHistory} desde 'vue-router'; 

const enrutador = createRouter({ 
    historial: createWebHistory(), 
    rutas: [ 
        { 
            ruta: '/', 
            componente: () => import('./pages/Login.vue') 
        }, 
        { 
            ruta: '/register', 
            componente: () => import('./pages/Register.vue') 
        }, 
        { 
            ruta: '/home', 
            componente: () => import('./pages/Home.

Debido a la simplicidad del proyecto, básicamente utilizamos Laravel Sanctum para manejar la autenticación de la página de inicio de sesión y luego guardamos nuestros tokens en el almacenamiento local.

Para que otras solicitudes tengan éxito, el token se adjuntará al encabezado, lo que permitirá que Laravel identifique al usuario solicitante.

Aquí está nuestra página de inicio de sesión:

A continuación se muestra nuestra página de registro:

Finalmente, aquí están los bloques de código relevantes para ambos:

<!--Login.vue--> 
<plantilla> 
    <div class="mx-auto w-4/12 mt-10 bg-blue-200 p-4 rounded-lg"> <div class="bg 
        - 
            white sombra-lg redondeado-lg px-8 pt-6 pb-8 mb-2 flex flex-col" > 
        < 
            h1 class="text-gray-600 py-5 font-bold text-3xl"> Iniciar sesión </h1> 
            <ul class="list-disc text-red-400" v-for="(valor, índice) en errores" :key="index" v-if="tipo de errores === 'objeto'"> 
                <li>{ 
  
  {valor[0]}}</li> 
            </ul> 
            <p class="lista-disco texto-rojo -400" v-if="tipo de errores === 'cadena'">{ 
  
  {errores}}</p> 
            <form método="post" @submit.prevent="handleLogin"> 
            <div class="mb- 4"> 
                <etiqueta
                    class="block text-grey-dark text-sm font-bold mb-2" 
                    for="nombre de usuario" 
                > 
                    Dirección de correo electrónico 
                </label> 
                <input 
                    class="apariencia de sombra-ninguno borde redondeado w-full py-2 px- 3 texto-gris-oscuro" 
                    id="nombre de usuario" 
                    tipo="texto" 
                    v-model="form.correo electrónico" 
                    requerido 
                /> 
            </div> 
            <div class="mb-4"> 
                <label  
                    class="bloque de texto-gris-oscuro texto-sm fuente-bold mb-2"
                    for="contraseña" 
                > 
                    Contraseña
                </label> 
                <input 
                    class="apariencia de sombra-ninguno borde borde-rojo redondeado w-full py-2 px-3 texto-gris-oscuro mb-3" id="contraseña" tipo="contraseña" 
                    v 
                    - 
                    model= 
                    Se requiere "form.contraseña" 
                /> 
            </div> 
            <div class="flex items-center justify-between"> 
                <button 
                    class="bg-blue-500 hover:bg-blue-900 texto-blanco fuente-negrita py-2 px-4 redondeado" 
                    tipo="enviar" 
                >  
                    Iniciar sesión
                </button> 
                <router-link 
                    class="inline-block align-baseline font-bold text-sm text-blue hover:text-blue-darker" 
                    to="register" 
                > 
                    Regístrate 
                </router-link> 
            </div> 
            </ formulario> 
        </div> 
    </div> 
</template> 
exportar predeterminado { 
    setup() { 
        const errores = ref() 
        const enrutador = useRouter(); 
        forma constante = reactiva({ 
            correo electrónico: '', 
            contraseña: '',mensaje || 
                "" } 
            } 
        } 
        devolver { 
            formulario,

            errores, 
            handleLogin, 
        } 
} 
    }

Las vistas/páginas de Vue manejan todos, como crear, eliminar, actualizar y enumerar todos. Todas las operaciones realizan solicitudes al punto final con un token de usuario para autorización con Axios. Hogar

Veamos cómo se ven, seguido de los fragmentos relevantes:

<!-- Inicio --> 
<plantilla> 
    <div class="w-6/12 p-10 mx-auto"> 
        <div class="flex justify-between"> 
            <h1 class="text-2xl"> Todo </h1> 
            <span class="capitalize">Bienvenido { 
  
  { usuario && nombre.usuario }}, <button 
                class="text-orange-500 subrayado al pasar el mouse:sin subrayado redondeado-md" 
                @click="handleLogout">Cerrar sesión</button></span> 
        </div> 
        <input type="text" class="p-2 w-64 borde redondeado-md" v- model="todo" placeholder="Ingresa tu tarea"/> 
        <button class="bg-blue-600 text-white px-5 py-2 rounded-md ml-2 hover:bg-blue-400" @click= "addTodo">Agregar</button> 
        <Loader v-if="isLoading"/>
        <ul class="border-t mt-3 cursor-pointer"> 
            <li :class="`py-3 border-b text-gray-600 ${val.has_completed ? 'line-through' : ''}` " 
                v-for="(val, idx) en todos" :key="idx"> 
                <input type="checkbox" :checked="val.has_completed" @click="checked(idx)"/> 
                <span @ click="checked(val, idx)" class="pl-3">{ 
  
  { val.title }} </span> 
                <button class="float-right bg-red-400 px-2 text-white font- negrita redondeada-md hover:bg-red-600" 
                        @click="deleteTodo(val,idx)">× 
                </button> 
            </li> 
        </ul> 
    </div> 
</template> 
setup() {
    const todo = ref('') 
    const todos = ref([]) 
    const usuario = ref() 
    const isLoading = ref() 

    let router = useRouter(); 
    onMounted(() => { 
        autenticación() 
        handleTodos() 
    }); 

    autenticación const = async () => { 
        isLoading.value = true 
        try { 
            const req = await request('get', '/api/user') 
            user.value = req.data 
        } catch (e) { 
            await router.push ('/') 
        } 
    } 

    const handleTodos = async () => { 
        try { 
            const req = await request('get',
            todos.value = req.data.data 
        } catch (e) { 
            await router.push('/') 
        } 
        isLoading.value = false 
    } 

    const handleNewTodo = async (title) => { 
        try { 
            const data = {title: title } 
            const req = await request('post', '/api/todos', data) 
            if (req.data.message) { 
                isLoading.value = false 
                return alert(req.data.message) 
            } 
            todos.value.push( req.data.data) 
        } catch (e) { 
            await router.push('/') 
        } 
        isLoading.valor = falso 
    }

    const handleLogout = () => { 
        localStorage.removeItem('APP_DEMO_USER_TOKEN') 
        router.push('/') 
    } 

    const addTodo = () => { 
        if (todo.value === "") { 
            return alert("Todo no puede estar vacío"); 
        } 
        isLoading.value = true 
        handleNewTodo(todo.value) 
        todo.value = "" 
    } 

    const check = async (val, index) => { 
        try { 
            const data = {has_completed:!val.has_completed} 
            const req = await request( 'poner', `/api/todos/${val.id}`, datos) 
            if (req.data.message) { 
                isLoading.
                return alert(req.data.message) 
            } 
            todos.value[index].has_completed = !val.has_completed 
        } catch (e) { 
            await router.push('/') 
        } 
        isLoading.value = false 
    } 

    const deleteTodo = async ( val, index) => { 
        if (window.confirm("¿Estás seguro")) { 
            intenta { 
                const req = await request('delete', `/api/todos/${val.id}`) 
                if (req .data.message) { 
                    isLoading.value = false 
                    todos.value.splice(index, 1) 
                } 
            } catch (e) {
                await router.push('/') 
            } 
            isLoading.value = false 
        } 
    }

Para Laravel crearemos lo siguiente:

  • controlador(AuthController``TodoController)

  • modelo(,Todo``Usuario)

  • ruta (api)

  • middleware(). autenticación: santuario

Nuestra ruta está en , que maneja todos los puntos finales que utiliza Vue. api.php

Ruta::post('/auth/register', [AuthController::class, 'register']); 
Ruta::post('/auth/login', [AuthController::class, 'login']); 

Ruta::apiResource('todos', TodoController::class)->middleware('auth:sanctum'); 

Ruta::middleware('auth:sanctum')->get('/usuario', función (Solicitud $solicitud) { 
    return $solicitud->usuario(); 
});

La lógica de registro registra al usuario y crea un token. Controlador de autenticación

registro de función pública (Solicitud $ solicitud): \Illuminate\Http\JsonResponse 
{ 
    intentar { 
        //Validado 
        $validateUser = Validator::make($request->all(), 
        [ 
            'nombre' => 'requerido', 
            'correo electrónico' => 'requerido|correo electrónico|único:usuarios,correo electrónico', 
            'contraseña' => 'requerido' 
        ]); 

        if($validateUser->fails()){ 
            return respuesta()->json([ 
                'status' => false, 
                'mensaje' => 'error de validación', 
                'errores' => $validateUser->errors() 
            ] , 401); 
        } 

        $usuario = Usuario::crear([
            'nombre' => $solicitud->nombre, 
            'correo electrónico' => $solicitud->correo electrónico, 
            'contraseña' => Hash::make($solicitud->contraseña) 
        ], 201); 

        return respuesta()->json([ 
            'estado' => verdadero, 
            'mensaje' => 'Usuario creado exitosamente', 
            'token' => $usuario->createToken("API_TOKEN")->plainTextToken 
        ], 200); 

    } catch (\Throwable $e) { 
        return respuesta()->json([ 
            'estado' => falso, 
            'mensaje' => $e->getMessage() 
        ], 500); 
    } 
}

Una solicitud de verificación de inicio de sesión verifica que el usuario existe y luego crea un token:

inicio de sesión de función pública (Solicitud $ solicitud): \Illuminate\Http\JsonResponse 
{ 
    intentar { 
        //Validado 
        $validateUser = Validator::make($request->all(), 
            [ 
                'correo electrónico' => 'requerido', 
                'contraseña' => 'requerido' 
            ]); 
​if
        ($validateUser->fails()){ 
            return respuesta()->json([ 
                'estado' => falso, 
                'mensaje' => 'error de validación', 
                'errores' = > $validarUsuario->errores() 
            ], 401); 
        } 
​si
        (!Auth::
            return respuesta()->json([ 
                'estado' => falso, 
                'mensaje' => 'El correo electrónico y la contraseña no existen.', 
            ], 401); 
        } 
​$
        usuario = Usuario::where('correo electrónico', $solicitud->correo electrónico)->primero(); 
​return
        respuesta()->json([ 
            'estado' => verdadero, 
            'mensaje' => 'Registrado En Successfully', 
            'token' => $user->createToken("API_TOKEN")->plainTextToken 
        ], 200); 
​}
    catch (\Throwable $e) { 
        return respuesta()->json([ 
            'status' = > falso,
    } 
}

El punto final POST para agregar una nueva tarea pendiente se administra mediante un método en el controlador de tareas pendientes: . tienda``/api/todos

almacén de funciones públicas(Solicitud $solicitud): \Illuminate\Http\JsonResponse 
{ 
    $datos = Todo::where('user_id', $solicitud->usuario()->id)->where('título', $solicitud- >título); 
    if ($datos->primero()) { 
        return respuesta()->json(['estado' => falso, 'mensaje' => 'Ya existe']); 
    } 
    $req = $solicitud->todos(); 
    $req['user_id'] = $solicitud->usuario()->id; 
    $datos = Todo::create($req); 
    return respuesta()->json(['estado' => verdadero, 'datos' => $datos], 201); 
}

Esto administrará el punto final de actualización, al que se llama cuando el usuario completa una tarea pendiente, en . Todo``/api/todos/id

actualización de función pública (Solicitud $solicitud, $id): \Illuminate\Http\JsonResponse 
{ 
    $validateUser = Validator::make($request->all(), 
        [ 
            'has_completed' => 'requerido', 
        ]); 

    if ($validateUser->fails()) { 
        return respuesta()->json([ 
            'status' => false, 
            'mensaje' => 'error de validación', 
            'errores' => $validateUser->errors() 
        ] , 401); 
    } 

    $datos = Todo::find($id); 
    $datos->has_completed = $solicitud->has_completed; 
    $datos->actualizar(); 
    devolver respuesta()->json(['estado' => verdadero, 'datos' => $datos], 202); 
}

Cuando un usuario elimina, se llamará al punto final, que lo manejará: Todo``/api/todos/id

función pública destruir(int $id): \Illuminate\Http\JsonResponse 
{ 
    throw_if(!$id, 'falta el ID de todo'); 
    Todo::findOrFail($id)->delete(); 
    return respuesta()->json(['estado' => verdadero, 'mensaje' => 'todo eliminado']); 
}

¡Excelente trabajo, creamos una aplicación de una sola página usando Laravel y Vue! A continuación se muestra el resultado final de nuestra aplicación de tareas pendientes. ¡Bien hecho, creamos una aplicación de una sola página usando Laravel y Vue! :

en conclusión

Pudimos determinar que era mucho más sencillo crear una aplicación de lista de tareas y autenticación de usuario simple con Vue y Laravel que con una combinación tradicional de PHP/Vue, lo que probablemente requirió más trabajo de configuración.

En mi opinión, la combinación de Vue y Laravel facilita el desarrollo de aplicaciones de una sola página porque no hay necesidad de preocuparse por el enrutamiento, el middleware o el manejo de CORS. Déjeme saber sobre sus experiencias en el desarrollo de SPA en la sección de comentarios a continuación.

Supongo que te gusta

Origin blog.csdn.net/weixin_47967031/article/details/132590611
Recomendado
Clasificación