question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Vue router and javalin-vue

See original GitHub issue

After a month, and two apps later my first experience of Javalin, I ran into a problem I can’t figure out.

I used JavalinVue to support my dashboard page. I have a dashboard with a fixed top navbar and an also fixed (for the sake of the example) and always visible right sidebar. When I open the dashboard, it displays as it should.

image

However, when I click on the brand (navigating to /ownerhome) or the menu item (navigating to /services), it doesn’t display (replace the router-view) to the given component. Additionally, while the navbar remains, the sidebar disappears.

image

What I would like to achieve: keep the top navbar and the sidebar (don’t reload them, because that’s costly) in spot and replace only the content. I tried a lot of options, but can’t find the reason. The console shows that the router.beforeEach is called and the url is changed.

layout.html

<html>
<head>
    <title>[[Application.name]]</title>
    <meta charset="utf8">
    <script src="/webjars/vue/2.6.10/dist/vue.min.js"></script>

    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium+Web">

    <link rel="stylesheet"
          href="https://maxst.icons8.com/vue-static/landings/line-awesome/line-awesome/1.3.0/css/line-awesome.min.css">

    <link rel="shortcut icon" href="/favicon.png" type="image/x-icon"/>

    <link type="text/css" rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootswatch/4.5.2/cyborg/bootstrap.min.css"/>
    <script src="https://unpkg.com/bootstrap-vue@2.18.0/dist/bootstrap-vue.min.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-vue/2.18.0/bootstrap-vue.min.css"
          integrity="sha512-oqSSCKWeQcVs+9Hek1tZlj8hMlLhDNI+NUmm56nBCsO4OLE8dyDpaUA/b2zGi+M9SML0xwGtk22ozH2qyqKipg=="
          crossorigin="anonymous"/>

    @componentRegistration
</head>
<body>
<main id="main-vue" v-cloak>
    @routeComponent
</main>
<script>
    const EventBus = new Vue({})

    Vue.config.devtools = true

    const routes = [
        {
            name: 'home',
            path: '/home',
            component: ownerhome
        },
        {
            name: 'services',
            path: '/services',
            component: ownerservices
        },
    ]

    const router = new VueRouter({
        routes 
    })

    router.beforeEach(async (to, from, next) => {
        console.log(to, next)
        next()
    })

    const vue = new Vue({router}).$mount("#main-vue");
</script>
</body>
</html>

It has nothing surprising: the only special is to add VueRouter support.

dashboard.vue

<template id="dashboard">
    <div >
        <app-frame>
            <router-view></router-view>
        </app-frame>
    </div>
</template>
<script>
Vue.component("dashboard", {
    template: "#dashboard"
});


</script>
<style>
</style>

app-frame.vue

<template id="app-frame">
    <v-app>
        <v-content>
            <ownernavbar></ownernavbar>
            <glossarysidebar></glossarysidebar>
            <v-container>
                <slot></slot>
            </v-container>
        </v-content>
    </v-app>
</template>
<script>
Vue.component("app-frame", {template: "#app-frame"});
</script>
<style>
</style>

This two files are straightforward.

home.vue

<template id="ownerhome">
    <v-content class="bg-info">
        <b-card title="test" tag="article" style="max-width: 20rem;">
            <b-card-text>
                Text
            </b-card-text>

            <b-button href="#" variant="primary">Go somewhere</b-button>
        </b-card>
    </v-content>
</template>
<script>
Vue.component("ownerhome", {
    template: "#ownerhome"
})
</script>
<style>
</style>

I feel I miss some nuance, but can’t find it. 😦

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:14 (14 by maintainers)

github_iconTop GitHub Comments

2reactions
balage1551commented, Oct 25, 2020

Thanks for the answers. They will most probably make my SPA concept needless.

This optimizeDependencies option is great and I’ll check it. The stateFunction is also a great alternative for my problem. It is almost identical to handling client side state. Almost, because it has some differences: it contains only data, so if I need to make some post process or would like decorate the pure data with some utility functions, it still has to do with each reload. But this I could live with. A few questions about the use of this function: as I saw in the source (I am away and could only browse the source code of Javalin, but can’t try these features) that this function produces Any and this value is serialized to JSON. Could I inject a pure JSON into the state as is? My server side already has it’s JSON serialization (not pure GSON, they build up the JSON by themself), so I would like to use a stateFunction producing JSON. Is it possible?

Also, I will try to figure out why the flickering happens, because it is clear now that the window is cleared long before the page is displayed. I have a guess, but has to check it.

1reaction
TareqKcommented, Oct 23, 2020

just to also add my 2C, you can also change the caching policy for production for views, by setting

JavalinVue.cacheControl = "max-age=259200,must-revalidate";//cache files for 3 days

you can also do a bit of UX optimization, by isolating your main theme colors and blocks into its own theme.css and loading that as the first file in your head tag and having that cached as well.

If you want something that is a huge SPA with complex views, you might be better off using Static files and creating a normal npm project based on Vue js and having a postbuild script that moves them into an appropriate java resources folder.

Though when using JavalinVue.optimizeDependncies = true, you can knock down pages to be into single digit kilobytes

You can also hack in an HTML compressor using an app.after middleware to knock it down even further, but that takes CPU on the server-side

Read more comments on GitHub >

github_iconTop Results From Across the Web

Vue router and javalin-vue · Issue #1093 - GitHub
I used JavalinVue to support my dashboard page. I have a dashboard with a fixed top navbar and an also fixed (for the...
Read more >
Clean Vue frontends without the hassle - Javalin
In this tutorial you'll learn how to create simple frontends with Javalin and Vue.The tutorial is quite extensive, and covers single-file ...
Read more >
Clean web frontends without the hassle (Javalin/Vue article ...
Most basic of basic questions: You used Webstorm as the IDE, right? IntelliJ only seems to be able to use Vue.JS in its...
Read more >
Using webjars with Javalin and Vue - Stack Overflow
i've been working with vue and Javalin for a short time, but i finally got ... A little example that works for me...
Read more >
API Reference | Vue Router
<router-link> is the component for enabling user navigation in a router-enabled app. The target location is specified with the to prop. It renders...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found