Difference between revisions of "Nuxt.JS Routing"

From WikiOD
Line 13: Line 13:
 
  -----| index.vue
 
  -----| index.vue
 
  -----| one.vue
 
  -----| one.vue
  --| index.vue</code>
+
  --| index.vue
 +
</code>
 
Then, the routing configuration automatically generated by Nuxt.js is as follows:
 
Then, the routing configuration automatically generated by Nuxt.js is as follows:
 
<code>
 
<code>

Revision as of 10:15, 24 August 2021

Nuxt.js automatically generates the routing configuration of the vue-router module based on the pages directory structure.

To use routing between pages, we recommend using the <nuxt-link>  tag.

For example:

   <nuxt-link to="/">Home</nuxt-link>
Basic routing

Suppose the directory structure of pages is as follows:


pages/

--| user/
-----| index.vue
-----| one.vue
--| index.vue

Then, the routing configuration automatically generated by Nuxt.js is as follows: router: {

   routes: [
     {
       name: 'index',
       path: '/',
       component: 'pages/index.vue'
     },
     {
       name: 'user',



       path: '/user',
       component: 'pages/user/index.vue'
     },
     {
       name: 'user-one',
       path: '/user/one',
       component: 'pages/user/one.vue'
     }
   ]
 }

Dynamic routing

To define a dynamic route with parameters in Nuxt.js, you need to create a Vue file or directory with the corresponding underscore as the prefix.

The following directory structure:

pages/
--| _slug/
-----| comments.vue
-----| index.vue
--| users/
-----| _id.vue
--| index.vue

The corresponding routing configuration table generated by Nuxt.js is:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'users-id',
      path: '/users/:id?',
      component: 'pages/users/_id.vue'
    },
    {
      name: 'slug',
      path: '/:slug',
      component: 'pages/_slug/index.vue'
    },
    {
      name: 'slug-comments',
      path: '/:slug/comments',
      component: 'pages/_slug/comments.vue'
    }
  ]
}

You will find that the route path named users-id has the :id? parameter, indicating that the route is optional. If you want to set it as a required route, you need to create an index.vue file in the users/_id directory.

:API Configuration generate

Warning: The generate command ignores dynamic routing:  API Configuration generate

Routing parameter verification

Nuxt.js allows you to define parameter verification methods in dynamic routing components.

For example: pages/users/_id.vue

export default {
  validate ({ params }) {
    // Must be of type number
    return /^\d+$/.test(params.id)
  }
}

If the value returned by the verification method is not true or resolve in the Promise resolves to false or throws an Error, Nuxt.js will automatically load and display a 404 error page or a 500 error page.

For information about routing parameter verification, please refer to  page verification API .

Nested routing

You can create nested routes for Nuxt.js applications through sub-routes of vue-router.

To create an embedded sub-route, you need to add a Vue file and a directory with the same name as the file to store the sub-view components.

Warning: Don't forget to add <nuxt-child/> to the parent component (.vue file) to display the content of the child view.

Suppose the file structure is as follows:

pages/
--| users/
-----| _id.vue
-----| index.vue
--| users.vue

The routing configuration automatically generated by Nuxt.js is as follows:

router: {
  routes: [
    {
      path: '/users',
      component: 'pages/users.vue',
      children: [
        {
          path: '',
          component: 'pages/users/index.vue',
          name: 'users'
        },
        {
          path: ':id',
          component: 'pages/users/_id.vue',
          name: 'users-id'
        }
      ]
    }
  ]
}
Dynamic nested routing

This application scenario is relatively rare, but Nuxt.js still supports: Configure dynamic sub-routes under dynamic routing.

Suppose the file structure is as follows:

pages/
--| _category/
-----| _subCategory/
--------| _id.vue
--------| index.vue
-----| _subCategory.vue
-----| index.vue
--| _category.vue
--| index.vue

The routing configuration automatically generated by Nuxt.js is as follows:

router: {
  routes: [
    {
      path: '/',
      component: 'pages/index.vue',
      name: 'index'
    },
    {
      path: '/:category',
      component: 'pages/_category.vue',
      children: [
        {
          path: '',
          component: 'pages/_category/index.vue',
          name: 'category'
        },
        {
          path: ':subCategory',
          component: 'pages/_category/_subCategory.vue',
          children: [
            {
              path: '',
              component: 'pages/_category/_subCategory/index.vue',
              name: 'category-subCategory'
            },
            {
              path: ':id',
              component: 'pages/_category/_subCategory/_id.vue',
              name: 'category-subCategory-id'
            }
          ]
        }
      ]
    }
  ]
}

Dynamic nested routing

This application scenario is relatively rare, but Nuxt.js still supports: Configure dynamic sub-routes under dynamic routing.

Suppose the file structure is as follows:

pages/
--| _category/
-----| _subCategory/
--------| _id.vue
--------| index.vue
-----| _subCategory.vue
-----| index.vue
--| _category.vue
--| index.vue

The routing configuration automatically generated by Nuxt.js is as follows:

router: {
  routes: [
    {
      path: '/',
      component: 'pages/index.vue',
      name: 'index'
    },
    {
      path: '/:category',
      component: 'pages/_category.vue',
      children: [
        {
          path: '',
          component: 'pages/_category/index.vue',
          name: 'category'
        },
        {
          path: ':subCategory',
          component: 'pages/_category/_subCategory.vue',
          children: [
            {
              path: '',
              component: 'pages/_category/_subCategory/index.vue',
              name: 'category-subCategory'
            },
            {
              path: ':id',
              component: 'pages/_category/_subCategory/_id.vue',
              name: 'category-subCategory-id'
            }
          ]
        }
      ]
    }
  ]
}
Dynamic nested routing with unknown nesting depth

If you don't know the depth of the URL structure, you can use _.vue to dynamically match nested paths. This will handle the case of a mismatch with a more specific request.

File structure:

pages/
--| people/
-----| _id.vue
-----| index.vue
--| _.vue
--| index.vue

Will handle requests like this:

Path File
/ index.vue
/people people/index.vue
/people/123 people/_id.vue
/about _.vue
/about/careers _.vue
/about/careers/chicago _.vue

Note: Processing the 404 pages now conforms to the logic of the _.vue page. For more information about 404 redirects, click here .

Named view

To render named views, you can use the <nuxt name="top"/> or <nuxt-child name="top"/> component in the layout/page. To specify the named view of the page, we need to extend the router configuration in the nuxt.config.js file:

export default {
  router: {
    extendRoutes (routes, resolve) {
      const index = routes.findIndex(route => route.name === 'main')
      routes[index] = {
        ...routes[index],
        components: {
          default: routes[index].component,
          top: resolve(__dirname, 'components/mainTop.vue')
        },
        chunkNames: {
          top: 'components/mainTop'
        }
      }
    }
  }
}

It needs to extend the route with two attributes components and chunkNames. The named view name in this configuration example is top. Look at an example: named view example.

SPA fallback

You can also enable SPA fallback for dynamic routing. When using mode:'spa' mode, Nuxt.js will output an additional file the same as index.html. If no files match, most static hosting services can be configured to use SPA templates. The generated file does not contain header information or any HTML, but it will still parse and load the data in the API.

We enable it in the nuxt.config.js file:

export default {
  generate: {
    fallback: true, // if you want to use '404.html'
    fallback: 'my-fallback/file.html' // if your hosting needs a custom location
  }
}
Implemented on Surge

Surge  can handle 200.html and 404.html, generate. fallback is set to 200.html by default, so there is no need to change it.

Implemented on GitHub Pages and Netlify

GitHub Pages and Netlify automatically recognize the 404.html file, so all we need to do is set generate. fallback to true!

Implemented on Firebase Hosting

To use it on Firebase Hosting, configure generate.fallback to true and use the following configuration ( more info ):

To use it on Firebase Hosting, configure generate.fallback to true and use the following configuration ( more info ):{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/404.html"
      }
    ]
  }
}
Transition effect

Nuxt.js uses the <transition> component of Vue.js to realize the transition effect when switching routes.

Global transition animation settings

Tip: The transition effect name used by Nuxt.js by default is page

If we want to make every page switch have a fade effect, we need to create a CSS file common to all routes. So we can create this file in the assets/ directory:

Add the following styles in the global style file assets/main.css:

.page-enter-active, .page-leave-active {
  transition: opacity .5s;
}
.page-enter, .page-leave-active {
  opacity: 0;
}

Then add it to the nuxt.config.js file:

module.exports = {
  css: [
    'assets/main.css'
  ]
}

For more information about the transition effect transition property configuration, please refer to the  page transition effect API.

Page transition animation settings

If you want to customize transition effects for a certain page, just configure the transition field in the page component:

Add the following content in the global style assets/main.css:

.test-enter-active, .test-leave-active {
  transition: opacity .5s;
}
.test-enter, .test-leave-active {
  opacity: 0;
}

Then we set the value of the transition property in the page component to test:

export default {
  transition: 'test'
}

For more information about the transition effect transition property configuration, please refer to the  page transition effect API .

Middleware

Middleware allows you to define a custom function to run on a page or group of pages before rendering.

Each middleware should be placed in the middleware/ directory. The name of the file name will become the middleware name (middleware/auth.js will become the auth middleware).

A middleware receives context as the first parameter:

export default function (context) {
  context.userAgent = process.server ? context.req.headers['user-agent'] : navigator.userAgent
}

Middleware execution flow sequence:

  1. nuxt.config.js
  2. Match layout
  3. Match page

Middleware can be executed asynchronously, just return a Promise or use the second callback as the first parameter:

middleware/stats.js

import axios from 'axios'

export default function ({ route }) {
  return axios.post('http://my-stats-api.com', {
    url: route.fullPath
  })
}

Then use middleware in your nuxt.config.js, layouts or pages:

nuxt.config.js

module.exports = {
  router: {
    middleware: 'stats'
  }
}

Now, the stats middleware will be called every time the route changes.

You can also add middleware to the specified layout or page:

pages/index.vue or layouts/default.vue

export default {
  middleware: 'stats'
}

If you want to see a real example of using middleware, please refer to example-auth0 on GitHub.