Skip to content

路由

约定式路由

介绍

Nuxt.js 是一个基于 Vue.js 的服务端渲染框架,它提供了一种约定式路由机制,使得开发者无需手动定义路由表,就可以根据文件结构自动生成路由。这是 Nuxt.js 的一个强大特性,简化了路由管理的工作。

约定式路由

在 Nuxt.js 中,页面组件存放在 pages 目录下。Nuxt 会根据 pages 目录的文件结构自动生成对应的路由。以下是一些基本的约定:

  1. 基础路由:
    • 如果在 pages 目录下创建一个 about.vue 文件,它将自动生成一个指向 /about 的路由。
  2. 动态路由:
    • 若需要创建动态路由,可以在 pages 目录下使用下划线作为参数前缀。例如,创建 user/_id.vue,它将匹配如 /user/123 这样的动态路由,参数 id 可以在页面组件中通过 this.$route.params.id 获取。
  3. 嵌套路由:
    • 可以在 pages 目录内创建子目录,从而自动生成嵌套路由。例如,pages/blog/index.vuepages/blog/post.vue 将生成 /blog/blog/post 路由。
  4. 自定义路由:
    • 如果需要更多自定义的路由行为,你可以通过在项目的根目录下创建一个 nuxt.config.js 文件,使用 router.extendRoutes 函数进行配置。

示例

假设你的项目结构如下:

/pages
  /index.vue
  /about.vue
  /user
    /_id.vue
  /blog
    /index.vue
    /post.vue

自动生成的路由将是:

  • / 映射到 pages/index.vue
  • /about 映射到 pages/about.vue
  • /user/:id 映射到 pages/user/_id.vue
  • /blog 映射到 pages/blog/index.vue
  • /blog/post 映射到 pages/blog/post.vue

自定义路由

nuxt.config.js 中,你可以这样自定义路由:

javascript
export default {
  router: {
    extendRoutes(routes, resolve) {
      routes.push({
        name: 'custom',
        path: '/custom-path',
        component: resolve(__dirname, 'pages/custom.vue')
      });
    }
  }
}

这种方式允许你添加不基于 pages 目录结构的自定义路由。

Nuxt.js 的约定式路由大大简化了路由管理的工作,使得开发者可以更专注于页面组件的开发,而不需要花费大量时间在路由配置上。

用法

详细用法请参考本站 示例

layouts/default.vue 内容如下:

vue
<template>
    <div>
        <!-- 一级路由 -->
        <nuxt-link to="/">首页</nuxt-link>
        <nuxt-link to="/register">注册</nuxt-link>
        <nuxt-link to="/goods">商品列表</nuxt-link>

        <!-- 用于显示nuxt-link跳转,相当于router-view -->
        <nuxt/>
    </div>
</template>

路由 / 对应 pages/index.vue 页面,内容如下:

vue
<template>
  <div>
    首页
  </div>
</template>

<script>
export default {
    name: "IndexPage"
}
</script>

路由 /register 对应 pages/register.vue 页面,内容如下:

vue
<template>
    <div>注册</div>
</template>

路由 /goods 对应 pages/goods/index.vue 页面,内容如下:

vue
<template>
    <div>
        <div>商品列表</div>

        <!-- 二级路由: 商品详情,创建目录 pages/goods/_id.vue 目录用于表达路由结构 -->
        <nuxt-link to="/goods/1?p1=1&p2=11">商品1</nuxt-link>
        <nuxt-link to="/goods/2?p1=2&p2=22">商品2</nuxt-link>
        <nuxt-link :to="{ name: 'goods-id', params: { id: 3 }, query: { p1: 3, p2: 33 } }">商品3</nuxt-link>
        <a href="#" @click="handleClick">商品5</a>

        <!-- 用于显示nuxt-link跳转,相当于router-view -->
        <nuxt />
    </div>
</template>

<script>
export default {
    methods: {
        handleClick() {
            // https://stackoverflow.com/questions/64992189/how-to-achieve-programatic-routing-in-nuxt
            this.$router.push({ name: 'goods-id', params: { id: 5 }, query: { p1: 5, p2: 55 } })
        }
    }
}
</script>

路由 /goods/1?p1=1&p2=11 对应 pages/goods/_id.vue 页面,内容如下:

vue
<template>
    <div>
        <div>商品详情</div>
        <div>
            <!-- https://www.coder.work/article/1035775 -->
            this.$route.fullPath: {{ this.$route.fullPath }}<br/>
            this.$route.path: {{ this.$route.path }}<br/>
            this.$route.params: {{ this.$route.params }}<br/>
            this.$route.query: {{ this.$route.query }}<br/>
        </div>
    </div>
</template>

扩展路由(自定义路由)

详细用法请参考本站 示例

nuxt.config.js 内容如下:

javascript
export default {
  router: {
    extendRoutes(routes, resolve) {
      routes.push({
        name: "component1",
        path: "/component1",
        component: resolve(__dirname, "components/sub/Component1.vue")
      })

      routes.push({
        name: "component2",
        path: "/component2",
        component: resolve(__dirname, "components/sub/Component2.vue")
      })

      routes.push({
        name: "component3",
        path: "/component3",
        component: resolve(__dirname, "components/Component3.vue")
      })
    }
  }
}

layouts/default.vue 内容如下:

vue
<template>
    <div>
        <NuxtLink to="/">首页</NuxtLink>
        <NuxtLink to="/component1">组件1</NuxtLink>
        <NuxtLink to="/component2">组件2</NuxtLink>
        <NuxtLink to="/component3">组件3</NuxtLink>

        <nuxt />
    </div>
</template>

components/Component3.vue 内容如下:

vue
<template>
    <div>
        <ComponentInclude1></ComponentInclude1>
        <div>组件3</div>
    </div>
</template>

components/sub/ComponentInclude1.vue 内容如下:

vue
<template>
    <div>
        公共引用组件
    </div>
</template>

<script>
export default {
    name: 'ComponentInclude1'
}
</script>

components/sub/Component1.vue 内容如下:

vue
<template>
    <div>
        <ComponentInclude1></ComponentInclude1>
        <div>组件1</div>
    </div>
</template>

<script>
export default {
    name: 'Component1',
}
</script>

components/sub/Component2.vue 内容如下:

vue
<template>
    <div>
        <ComponentInclude1></ComponentInclude1>
        <div>组件2</div>
    </div>
</template>

编程式跳转路由

https://stackoverflow.com/questions/64992189/how-to-achieve-programatic-routing-in-nuxt

javascript
this.$router.push({ name: 'goods-id', params: { id: 5 }, query: { p1: 5, p2: 55 } })
  • 跳转到路由 /goods/5?p1=5&p2=55