Skip to content

🧩 04. Uso de Ziggy en Vue 3

Ziggy se integra perfectamente con Vue 3, permitiendo utilizar las rutas de Laravel de manera elegante en tus componentes. Hay varias formas de integrar Ziggy en una aplicación Vue, dependiendo de la estructura y necesidades de tu proyecto.

Antes de utilizar Ziggy en tus componentes Vue, asegúrate de que está correctamente instalado y configurado en tu proyecto Laravel. Luego, puedes importar la función route en tus componentes Vue.

Configuración en main.js
// En tu archivo principal (main.js)
import { createApp } from 'vue';
import App from './App.vue';
import route from 'ziggy-js';
const app = createApp(App);
// Hacer que route esté disponible globalmente
app.config.globalProperties.$route = route;
app.mount('#app');

Si estás utilizando la Options API de Vue, puedes acceder a la función route a través de this.$route si la has configurado como una propiedad global:

Componente Vue con Options API
<template>
<div>
<a :href="profileUrl">Ver perfil</a>
<button @click="goToDashboard">Ir al Dashboard</button>
</div>
</template>
<script>
export default {
data() {
return {
userId: 1
};
},
computed: {
profileUrl() {
return this.$route('users.profile', { id: this.userId });
}
},
methods: {
goToDashboard() {
window.location.href = this.$route('dashboard');
}
}
};
</script>

Alternativamente, puedes importar la función route directamente en cada componente:

<template>
<div>
<a :href="profileUrl">Ver perfil</a>
</div>
</template>
<script>
import route from 'ziggy-js';
export default {
data() {
return {
userId: 1
};
},
computed: {
profileUrl() {
return route('users.profile', { id: this.userId });
}
}
};
</script>

Vue 3 introdujo la Composition API, que ofrece una forma más flexible de organizar la lógica de los componentes. Ziggy se integra perfectamente con esta API.

Componente Vue con Composition API
<template>
<div>
<a :href="profileUrl">Ver perfil</a>
<button @click="goToDashboard">Ir al Dashboard</button>
</div>
</template>
<script>
import { ref, computed } from 'vue';
import route from 'ziggy-js';
export default {
setup() {
const userId = ref(1);
const profileUrl = computed(() => {
return route('users.profile', { id: userId.value });
});
const goToDashboard = () => {
window.location.href = route('dashboard');
};
return {
userId,
profileUrl,
goToDashboard
};
}
};
</script>

Una práctica recomendada en Vue 3 es crear composables reutilizables. Puedes crear un composable para Ziggy que encapsule la funcionalidad de generación de rutas:

composables/useRoute.js
import route from 'ziggy-js';
import { computed } from 'vue';
export function useRoute() {
const generateUrl = (name, params = {}) => {
return route(name, params);
};
const checkIfRouteExists = (name) => {
return route().has(name);
};
const getAllRoutes = () => {
return route().all();
};
return {
route: generateUrl,
hasRoute: checkIfRouteExists,
allRoutes: getAllRoutes
};
}

Luego puedes usar este composable en tus componentes:

<template>
<div>
<a :href="userProfileUrl">Perfil</a>
<p v-if="routeExists">La ruta existe</p>
</div>
</template>
<script>
import { ref, computed } from 'vue';
import { useRoute } from '../composables/useRoute';
export default {
setup() {
const { route, hasRoute } = useRoute();
const userId = ref(1);
const userProfileUrl = computed(() => {
return route('users.profile', { id: userId.value });
});
const routeExists = computed(() => {
return hasRoute('users.profile');
});
return {
userProfileUrl,
routeExists
};
}
};
</script>

Vue 3 introdujo la sintaxis <script setup>, que simplifica aún más el uso de la Composition API. Puedes utilizar Ziggy directamente en esta sintaxis:

Componente Vue con <script setup>
<template>
<div>
<h1>Perfil de Usuario</h1>
<a :href="profileUrl">Editar perfil</a>
<button @click="goToSettings">Configuración</button>
<div v-if="isLoading">Cargando...</div>
<div v-else>
<p>Nombre: {{ user.name }}</p>
<p>Email: {{ user.email }}</p>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import axios from 'axios';
import route from 'ziggy-js';
// Props
const props = defineProps({
userId: {
type: Number,
required: true
}
});
// Estado reactivo
const user = ref({});
const isLoading = ref(true);
// URLs generadas con Ziggy
const profileUrl = computed(() => {
return route('users.edit', { user: props.userId });
});
// Métodos
const goToSettings = () => {
window.location.href = route('users.settings', { user: props.userId });
};
const fetchUserData = async () => {
try {
const response = await axios.get(route('api.users.show', { user: props.userId }));
user.value = response.data;
} catch (error) {
console.error('Error al cargar datos del usuario:', error);
} finally {
isLoading.value = false;
}
};
// Ciclo de vida
onMounted(() => {
fetchUserData();
});
</script>

Cómo pasar Ziggy con provide/inject si se necesita globalmente

Section titled “Cómo pasar Ziggy con provide/inject si se necesita globalmente”

Si necesitas que Ziggy esté disponible en toda tu aplicación Vue sin tener que importarlo en cada componente, puedes utilizar el sistema provide/inject de Vue 3.

Configuración global con provide
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import route from 'ziggy-js';
import { Ziggy } from './ziggy';
const app = createApp(App);
// Proporcionar Ziggy a toda la aplicación
app.provide('ziggy', {
route,
config: Ziggy
});
app.mount('#app');
<template>
<div>
<a :href="dashboardUrl">Dashboard</a>
</div>
</template>
<script>
export default {
inject: ['ziggy'],
computed: {
dashboardUrl() {
return this.ziggy.route('dashboard');
}
}
};
</script>

Si estás utilizando Vue Router junto con Ziggy, puedes combinarlos para aprovechar lo mejor de ambos mundos:

Integración con Vue Router
// router/index.js
import { createRouter, createWebHistory } from 'vue-router';
import route from 'ziggy-js';
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/',
name: 'home',
component: () => import('../views/Home.vue')
},
{
path: '/users/:id',
name: 'users.show',
component: () => import('../views/User.vue'),
props: true
}
// Más rutas...
]
});
// Middleware para sincronizar Vue Router con Ziggy
router.beforeEach((to, from, next) => {
// Si la ruta de Vue Router tiene un nombre que coincide con una ruta de Ziggy,
// podemos usar los parámetros de la ruta para generar la URL correcta
if (route().has(to.name)) {
const ziggyUrl = route(to.name, to.params);
console.log('Navegando a ' +to.name+ ' ('+ziggyUrl+')');
}
next();
});
export default router;
<template>
<form @submit.prevent="submitForm">
<div>
<label for="name">Nombre:</label>
<input id="name" v-model="form.name" type="text">
</div>
<div>
<label for="email">Email:</label>
<input id="email" v-model="form.email" type="email">
</div>
<button type="submit" :disabled="isSubmitting">{{ isSubmitting ? 'Enviando...' : 'Guardar' }}</button>
</form>
</template>
<script setup>
import { ref } from 'vue';
import axios from 'axios';
import route from 'ziggy-js';
const form = ref({
name: '',
email: ''
});
const isSubmitting = ref(false);
const submitForm = async () => {
isSubmitting.value = true;
try {
const response = await axios.post(route('api.users.store'), form.value);
alert('Usuario creado con éxito!');
form.value = { name: '', email: '' };
} catch (error) {
console.error('Error al crear usuario:', error);
alert('Error al crear usuario');
} finally {
isSubmitting.value = false;
}
};
</script>
🐝