Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use route() in setup() of vue 3 component? #454

Closed
sprklinginfo opened this issue Aug 21, 2021 · 6 comments
Closed

How to use route() in setup() of vue 3 component? #454

sprklinginfo opened this issue Aug 21, 2021 · 6 comments

Comments

@sprklinginfo
Copy link

Ziggy version

v1.3.5

Laravel version

v8.54.0

Description

Working on a project with Laravel/Inertia stack (from breeze starter kit). Here is a part of code in app.js

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => require(`./Pages/${name}.vue`),
    setup({ el, app, props, plugin }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .use(ElementPlus, { locale })
            .mixin({ methods: route }) // avoid namespace conflict with Element Plus NaveMenu component
            .mount(el);
    },
});

I am trying to use composition API on my components. I got 'route() undefined' error if I try using 'ctx.route()'. So my question is how I can use route() helper in setup() to access route params? Thanks!

Ziggy call and context

//

Ziggy configuration

//

Route definition

//
@sprklinginfo
Copy link
Author

can anyone help pls? or point me in the right direction? Thanks!!

@bakerkretzmar
Copy link
Collaborator

@sprklinginfo I haven't used the composition API but I think you don't have access to any methods inside setup() because there's no component instance yet: https://v3.vuejs.org/guide/composition-api-setup.html#accessing-component-properties. You should be able to use route() normally inside the template part of the component, but to use it in setup() I think you'd have to import it and set it up manually each time, something like this (pseudo-code, I didn't try to run this):

<script>
import route from `ziggy`;
import Ziggy from `./ziggy.js`;

export default {
    setup() {
        route('home', undefined, undefined, Ziggy); // https://my-app.test
    }
}
</script>

Can you try that and see if it works?

@sprklinginfo
Copy link
Author

thanks for the suggestion, @bakerkretzmar. Unfortunately, it doesn't work. I am trying to use composition API on all of my components as much as I can. In the Laravel Breeze starter kit, route() is imported as a mixin, so I probably have to use both options API and composition API if I want to use route() in the <script> section.

@bakerkretzmar
Copy link
Collaborator

@sprklinginfo I set up a new app with Breeze and can confirm this works. There are actually two different ways you can do this.

By default, the main layout in a Breeze-scaffolded app contains the @routes Blade directive, which makes the JS route() function available globally. So just route('dashboard') inside the setup method already works out of the box:

    setup() {
        const form = useForm({
            email: '',
            password: '',
            remember: false
        });

        console.log(route('dashboard'));

        return {
            form,
            submit() {
                form.post(route('login'), {
                    onFinish: () => this.form.reset('password'),
                })
            }
        }
    },

Note that it's just route(), not this.route().

If you don't use the @routes directive, you can set Ziggy up manually more or less like I did above. Remove .mixin({ methods: { route } }) from your app.js, then in your component:

import route from '../../../../vendor/tightenco/ziggy/dist';

    // ...

    setup() {
        const Ziggy = {"url":"http:\/\/issue-454-composition-api.test","port":null,"defaults":{},"routes":{"ignition.healthCheck":{"uri":"_ignition\/health-check","methods":["GET","HEAD"]},"ignition.executeSolution":{"uri":"_ignition\/execute-solution","methods":["POST"]},"ignition.shareReport":{"uri":"_ignition\/share-report","methods":["POST"]},"ignition.scripts":{"uri":"_ignition\/scripts\/{script}","methods":["GET","HEAD"]},"ignition.styles":{"uri":"_ignition\/styles\/{style}","methods":["GET","HEAD"]},"dashboard":{"uri":"dashboard","methods":["GET","HEAD"]},"register":{"uri":"register","methods":["GET","HEAD"]},"login":{"uri":"login","methods":["GET","HEAD"]},"password.request":{"uri":"forgot-password","methods":["GET","HEAD"]},"password.email":{"uri":"forgot-password","methods":["POST"]},"password.reset":{"uri":"reset-password\/{token}","methods":["GET","HEAD"]},"password.update":{"uri":"reset-password","methods":["POST"]},"verification.notice":{"uri":"verify-email","methods":["GET","HEAD"]},"verification.verify":{"uri":"verify-email\/{id}\/{hash}","methods":["GET","HEAD"]},"verification.send":{"uri":"email\/verification-notification","methods":["POST"]},"password.confirm":{"uri":"confirm-password","methods":["GET","HEAD"]},"logout":{"uri":"logout","methods":["POST"]}}};

        const form = useForm({
            email: '',
            password: '',
            remember: false
        });

        console.log(route('dashboard', undefined, undefined, Ziggy));

        return {
            form,
            // This makes `route()` available in the template
            route: (name, params, absolute, config = Ziggy) => route(name, params, absolute, config),
            submit() {
                form.post(route('login', undefined, undefined, Ziggy), {
                    onFinish: () => this.form.reset('password'),
                })
            }
        }
    },

In this second example, you can get your Ziggy config object from anywhere—if you generate it with php artisan ziggy:generate, instead of defining it manually in setup you can import it from that file.

@sprklinginfo
Copy link
Author

Million thanks @bakerkretzmar. One thing I didn't mention is that I had to alias the route() to appRoute() in the app.js since I also use Element Plus UI, which seems to conflict with its navMenu component:

vueApp.mixin({ methods: { appRoute: route } });

so in template, appRoute('register') etc. works. but in setup() it gave out 'appRoute is not defined' error. so I tried with options api, e.g. in data() to access this.appRoute().params which has no errors. After reading your new reply, I tried route() in setup() it works!!

when I tried with the second solution before, I didn't remove .mixin({ methods: { route } }) from the app.js, I guess that is why it didn't work.

@fahmiegerton
Copy link

I've got route is not a function when using with axios, but make it as a seperate function inside the setup and now it works!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants