Quadrubo
Quadrubo

Reputation: 41

How to load Vue directive with Inertia JS in Laravel (Jetstream)

My original app.js looked like this. I noticed I can't add Vue directives because the createApp has no variable.

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({ el, app, props, plugin }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .mixin({ methods: { route } })
            .mount(el);
    },
});

After some research this lead me to this where the directive still doesn't work. Any tips?

const clickOutside = {
    beforeMount: (el, binding) => {
        el.clickOutsideEvent = event => {
            // here I check that click was outside the el and his children
            if (!(el == event.target || el.contains(event.target))) {
                // and if it did, call method provided in attribute value
                binding.value();
            }
        };
        document.addEventListener("click", el.clickOutsideEvent);
    },
    unmounted: el => {
        document.removeEventListener("click", el.clickOutsideEvent);
    },
};

const el = document.getElementById('app');

const app = createApp({
    render: () =>
        h(InertiaApp, {
            initialPage: JSON.parse(el.dataset.page),
            resolveComponent: (name) => require(`./Pages/${name}`).default,
        }),
});

app.directive('click-outside', clickOutside);

app.mixin({ methods: { route } })
    .mixin({ directives: { clickOutside } })
    .use(InertiaPlugin);

app.mount(el);

Upvotes: 4

Views: 971

Answers (1)

Alexander
Alexander

Reputation: 21

I was running into the same issue. The solution is to add the directive within the Inertia render. Make sure to call app.mount(el) after binding the directive.

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({el, app, props, plugin}) {
        const app = createApp({render: () => h(app, props)})
            .use(plugin)
            .mixin({methods: {route}});
        app.directive('click-outside', {
            beforeMount: (el, binding) => {
                el.clickOutsideEvent = (event) => {
                    // here I check that click was outside the el and his children
                    if (!(el == event.target || el.contains(event.target))) {
                        // and if it did, call method provided in attribute value
                        binding.value();
                    }
                };
                document.addEventListener('click', el.clickOutsideEvent);
            },
            unmounted: (el) => {
                document.removeEventListener('click', el.clickOutsideEvent);
            },
        });

        app.mount(el);

        return app;
    },
});

Upvotes: 0

Related Questions