Home

Awesome

Vue Inertia Composable

jsdelivr CDN NPM Downloads Open in unpkg npm version Open in Gitpod Twitter Follow

A wrapper library for using Inertia with the Composition API in Vue2. Rewrite the function starting with $ (such as this.$inertia) to use and use (ex. const inertia = useInertia();) it. Please note that due to the implementation of Vue Inertia, it is not always API compatible with Vue3 Inertia.

Usage

Rewrite entry point script(such as main.ts or app.js).

import './bootstrap';
import '../css/app.css';

import Vue from 'vue';
import teleport from '@logue/vue2-helpers/teleport';
import { createInertiaApp } from '@inertiajs/vue2';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';

import ziggy from 'ziggy-js';

/** Application Name */
const appName =
  window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';

createInertiaApp({
  title: title => `${title} - ${appName}`,
  resolve: name =>
    // @ts-ignore
    resolvePageComponent(
      `./Pages/${name}.vue`,
      import.meta.glob('./Pages/**/*.vue')
    ),
  // @ts-ignore
  setup({ el, App, props, plugin }) {
    // Add route function.
    Vue.mixin({ methods: { route: ziggy } });
    // Register Inertia
    Vue.use(plugin);
    // Telepot for vue2.
    Vue.component('Teleport', teleport);
    // @ts-ignore
    Vue.use(ZiggyVue, Ziggy);

    return new Vue({ render: h => h(App, props) }).$mount(el);
  },
  progress: {
    color: import.meta.env.VITE_APP_INERTIA_PROGRESS_COLOR || '#4B5563',
  },
});

ssr.js or ssr.ts is bellow.

import { createInertiaApp } from '@inertiajs/vue2';
// @ts-ignore
import { createRenderer } from 'vue-server-renderer';
// @ts-ignore
import createServer from '@inertiajs/vue2/server';
import Vue from 'vue';
import teleport from '@logue/vue2-helpers/teleport';
import ziggy from 'ziggy-js';

/** Application Name */
const appName = import.meta.env.APP_NAME || 'Laravel';

createServer(page =>
  createInertiaApp({
    title: title => `${title} - ${appName}`,
    page,
    render: createRenderer().renderToString,
    resolve: name =>
      // @ts-ignore
      resolvePageComponent(
        `./Pages/${name}.vue`,
        import.meta.glob('./Pages/**/*.vue')
      ),
    // @ts-ignore
    setup({ App, props, plugin }) {
      // Add route function.
      Vue.mixin({ methods: { route: ziggy } });
      // Register Inertia
      Vue.use(plugin);
      // Telepot for vue2.
      Vue.component('Teleport', teleport);
      // @ts-ignore
      Vue.use(ZiggyVue, Ziggy);
      return new Vue({ render: h => h(App, props) });
    },
    progress: {
      color: import.meta.env.VITE_APP_INERTIA_PROGRESS_COLOR || '#4B5563',
    },
  })
);

The script tags of various vue files look like the following.

<template>
  <div class="container">
    <inertia-head title="Demo Page" />
    <input v-model="text" type="text" />
    <input v-model.number="no" type="number" />
    <button type="submit" @click="submit">Submit</button>
    <p><inertia-link :href="href">Link</inertia-link></p>
  </div>
</template>

<script lang="ts">
import { defineComponent, ref, type Ref } from 'vue';
import { useForm } from '@inertiajs/vue2';
import { route, InertiaLink } from 'vue-inertia-composable';

import { Head as InertiaHead } from '@inertiajs/inertia-vue';

export default defineComponent({
  /** Using Components */
  components: {
    InertiaHead,
    InertiaLink,
  },
  /** Setup */
  setup() {
    /** Inertia Form */
    const form = useForm({
      email: '',
      password: '',
      remember: false,
    }) as any;

    /** Form submit handler */
    const submit = () => {
      form.post(route('login'), {
        onFinish: () => form.reset('password'),
      });
    };

    return { form, submit, route };
  },
});
</script>

Available functions

These functions are basically used to access from within the setup() function.

Functioninformation
useInertia(): typeof Inertia & InertiaFormTraitAlias of Vue.$inertia
useHeadManager(): InertiaHeadManagerAlias of Vue.$headManager
usePage<SharedProps = Record<string, any>>(): Page<SharedProps>Alias of Vue.$page
useForm<TForm = Record<string, any>>(args: TForm): InertiaForm<TForm>Alias of Vue.$inertia.form(...)
route(name: string, params?: RouteParamsWithQueryOverload, RouteParam, absolute?: boolean, config?: Config): stringAlias of ziggy(...) or Vue.route(...)
InertiaLinkExperimental. See bellow.

Originally defined PageProps are similar to key-value pairs, but the value type is defined as unknown. As it is, the TypeScript check doesn't go well, so I changed the value type to any.

InertiaLink

This component was created experimentally because @inertiajs/vue's InertiaLink causes a type checking error. Not required if you don't use TypeScript.

See also

LICENSE

MIT

© 2022-2023 by Logue.