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

Vue router 4 support #110

Open
vis97c opened this issue Nov 30, 2021 · 6 comments
Open

Vue router 4 support #110

vis97c opened this issue Nov 30, 2021 · 6 comments

Comments

@vis97c
Copy link

vis97c commented Nov 30, 2021

Is there a roadmap to give support to vue router 4? So far the project works well enough with the nuxt-bridge with the drawback of not having reactivity. (watch for route changes)

Has anyone found a workaround? i tried resolving the router dependency to the v4 but nuxt with bridge is not compatible.

v4 comes with native support for vue3 with helper functions. Thanks for the project & thanks in advance for any further help.

@vis97c
Copy link
Author

vis97c commented Nov 30, 2021

Vue router 4 docs: https://next.router.vuejs.org/guide/

@vis97c
Copy link
Author

vis97c commented Nov 30, 2021

Figured out how to make the router reactive making use of one of vue3 awesome features:

In your router file:

import Vue from "vue";
import Router from "vue-router";
import { reactive } from "@vue/composition-api";

// "reactive" does all the magic
export const router = reactive(
  new Router({
    routes: [
      // your routes
    ],
    mode: "history",
    linkActiveClass: "is--route",
    linkExactActiveClass: "is--routeExact",
    scrollBehavior(_to, _from, savedPosition) {
      if (savedPosition) {
        return savedPosition;
      } else {
        return { x: 0, y: 0 };
      }
    },
  })
);
router.beforeEach((to, _from, next) => {
  /* It will change the title when the router is changed */
  if (process.browser) {
    // resets and defaults to stored title if it doesn't have one
    document.title = to.meta!.title ? to.meta!.title : "My project";
  }
  next();
});

Vue.use(Router);

/**
 * Router constructor, required by nuxt
 */
export function createRouter() {
  return router;
}

Then on your project components:

<script lang="ts">
  import { defineComponent, computed, watch } from "@vue/composition-api";
  import { router } from "~/routes/router";

  export default defineComponent({
    setup() {
      const route = computed(() => router.currentRoute);
      watch(
        route,
        () => {
          // do something after route change
        },
        {
          immediate: true,
          deep: true,
        }
      );
    }
  })
</script>

Hope it does help you. Since there is not a lot of people talking about this right now. Still keeping the issue open since the question is not related to this specific fix.

@tol64
Copy link

tol64 commented May 29, 2022

@vis97c

I work with Nuxt. And now I'm trying to translate a project from Nuxt 2 to Nuxt 3. In Nuxt 2 I used @nuxtjs/router module to configure the router.

Here is a brief example of the contents of router.js file:

import Vue from 'vue';
import Router from 'vue-router';

Vue.use(Router);

const page = path => () => import(`~/pages/${path}`).then(m => m.default || m);

let locale = '/:locale';

let routes = [
  { path: locale+'?/', name: 'index', component: page('index') },
  { path: locale+'/about', name: 'about', component: page('about') },
  { path: locale+'/test', name: 'test', component: page('test') },
  // ...
];

export function createRouter() {
  return new Router({
      routes: routes,
      mode: 'history'
  });
}

export function resetRouter() {
  const newRouter = createRouter();
  return newRouter.matcher;
}

Routing adjustments were made in the store\index.js file:

export const actions = {
  async nuxtServerInit({ state }) {
    let regPattern1 = new RegExp(/\/:locale(\(.*\))?\?\//);
    let regPattern2 = new RegExp(/\/:locale(\(.*\))?\//);
  
    this.$router.options.routes.forEach(r => {
      const replaceValue = '/:locale(' + state.data.locales.string + ')';
      if (r.path.match(regPattern1)) {
        r.path = r.path.replace(regPattern1, replaceValue + '?/');
      } 
      else if(r.path.match(regPattern2)) {
        r.path = r.path.replace(regPattern2, replaceValue + '/');
      }
    });
  
    this.$router.matcher = resetRouter();
  }
}

How can this be done for Nuxt 3?

@vis97c
Copy link
Author

vis97c commented May 29, 2022

@tol64 I have since moved away from that approach which I had to use due to the necessity of multiple components per view in my project. Now in nuxt3 layouts work in such a way that you can use slots making it easier to do such things. In your case I recommend you to follow the pages directory approach: https://v3.nuxtjs.org/guide/directory-structure/pages.

A possible file structure according to the information you provided could be like this:

image

Both folders have locale as dynamic parameter but the double brackets on the first one indicate that it is optional. Additional vue router parameters could be added to nuxt config or a "app/router.options.ts" file.

Additionally the logic behind locallization matching could be moved to a middleware to validate the usage of valid locales. https://v3.nuxtjs.org/guide/directory-structure/middleware

Hope this helps you. Good luck.

@tol64
Copy link

tol64 commented May 30, 2022

@vis97c

Thank you! This option is certainly interesting too and may be suitable for some simple cases.

But in my case, adding and removing site translations is done through the GUI in the admin area of the site. That is, there is no need to change the code and users do not even need to refresh the page for the update to apply.

Hopefully there will be an update for the @nuxtjs/router module soon:

image

https://modules.nuxtjs.org >>>

@TokugawaTakeshi
Copy link

TokugawaTakeshi commented Jan 9, 2023

Looks like no progress.

After I encountered with the incompatibility problem, I decided to check the source code.

if (!options.parsePages) {
    this.nuxt.hook('build:before', () => {
      this.nuxt.options.build.createRoutes = () => {
        return []
      }
    })
  }

There is no createRoutes anymore.
Also is has not understood how to assign the imported router from to actual nuxt router.
Would someone be so kind to give me the hint?

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