Nuxt3 中的路由的8种情况处理

134 阅读4分钟

在Vue 开发中配置路由需要我们自己安装vue-router, 然后在进行路由配置。 而在Nuxt项目中我们不需要这么麻烦。Nuxt 中的路由是基于文件结构的。你只要在项目根目录下的pages下新建的新建vue组件他会自动配置好路由。

先初始化一个Nuxt 项目, 执行: pnpm dlx nuxi@latest init nuxt-router 新建pages目录,在pages 下新建2个组件, login.vue, index.vue

pages直接目录下的组件

pages/login.vue

<template>
  <div>
    <p>登录页面</p>
  </div>
</template>

<script setup>
</script>

<style scoped>

</style>

pages/index.vue

<template>
  <div>
    <p>首页</p>
  </div>
</template>

<script setup>
</script>

<style scoped>

</style>

修改app.vue

<template>
  <div>
    <NuxtPage></NuxtPage>
  </div>
</template>

这里的NuxtPage 组件是Nuxt 内置的,不需要二外导入。相当于之前vue 开发中vue-router的RouterView组件。现在我们在地址栏输入: http://localhost:3000

image.png

可以看到就能访问到首页了,访问的就是index.vue(index命名的文件不需要输入路径) 地址栏输入:http://localhost:3000/login

image.png 可以看到也能正常访问login.vue这个页面

pages下面的文件夹下面能不能访问呢?

pages 嵌套文件夹下面的组件

我们在pages下新增如下结构:

image.png

pages/article/list.vue

<template>
  <div>
    <p><a href="#">Vue 标题</a></p>
    <p><a href="#">nuxt 标题</a></p>
  </div>
</template>

<script setup>
</script>

<style scoped>

</style>

现在在地址输入:http://localhost/article/list

image.png 可以看到嵌套的一样好使, 访问的时候加上文件夹名称就可以。

嵌套的文件夹下面的index.vue需要输入访问的时候需要输入index路径吗? 我们在article 下新建一个index.vue

pages/article/index.vue

<template>
  <div>
    <p>article 的index</p>
  </div>
</template>

<script setup>
</script>

<style scoped>

</style>

地址栏输入:http://localhost:3000/article/

image.png 可以发现嵌套的文件夹下面的index.vue 同样不需要输入index, 输入了index 反而会变成404

动态路由

在Nuxt3中将文件名用中括号括起来就可以实现动态路由,现在我们在article目录下添加[detail].vue

<template>
  <div>
    <p>文章详情</p>
  </div>
</template>

<script setup>
</script>

<style scoped>

</style>

地址栏输入:http://localhost:3000/article/1

image.png 可以看到这样就访问到了页面。我们还可以使用useRoute获取参数,代码修改如下:

<template>
  <div>
    <p>文章详情</p>
    <p>文章id:{{ articleId }}</p>
  </div>
</template>

<script setup>
const route = useRoute()
const articleId = route.params.detail
</script>

<style scoped>

</style>

运行结果:

image.png

可以看到我们就获取到了路由参数。

可选路由

在Nuxt3中使用双中括号实现可选路由,

image.png

pages/[[news]]/hot/list.vue 这里path中news 就成了可选的。我们地址栏输入http://localhost:3000/news/hot/listhttp://localhost:3000/hot/list 都能正常访问。

image.png

image.png

全局路由

这里的全局指的同一目录下面的同一层级。也就是我们在同一层级下输入其他文件不匹配的路由都不匹配时就会访问到的这个路由。在Nuxt中使用[...name.vue]的方式实现。 现在我们在pages目录下新建一个[...404].vue

<template>
  <div>
    <p>404</p>
  </div>
</template>

<script setup>
</script>

<style scoped>
p{
  font-size: 200px;
}
</style>

现在我们在地址栏随便输入一个path,当然不能输入大于一层的。http://localhost:3000/hello

image.png

在pages直接目录下没有文件名能匹配的上的,就访问了[...404].vue。

路由视图的嵌套

在Nuxt中,在同一层级中建一个文件名和文件夹相同的,然后在文件名的组件中加入NuxtPage组件占位,就能实现路由视图的嵌套。

在pages 下面添加如下结构:

image.png

访问:http://localhost:3000/about/detail

image.png

可以看到就实现了路由视图的嵌套。

导航组件NuxtLink

在Nuxt中使用NuxtLink组件实现页面的切换。现在我们添加以下结构:

image.png components/Header.vue

<template>
  <div style="width: 100%">
    <nav>
      <NuxtLink to="/">首页</NuxtLink>
      <NuxtLink to="/article/list">文章页面</NuxtLink>
      <NuxtLink to="/news/hot/list">热门新闻</NuxtLink>
      <NuxtLink to="/about">关于我们</NuxtLink>
    </nav>
  </div>
</template>

<script setup>
</script>

<style scoped>
nav{
  display: flex;
  height: 60px;
  box-shadow: 0px 5px 5px rgba(0,0,0, 0.2);
  align-items: center;
}

nav a{
  height: 100%;
  padding: 0 20px;
  text-decoration: none;
  line-height: 60px;
}
nav .router-link-active{
  background: #0f409e;
  color: #fff;
}
</style>

修改app.vue

<template>
  <div>
    <Header></Header>
    <NuxtPage class="page-wraper"></NuxtPage>
  </div>
</template>
<style>
*{
  margin: 0;
  padding: 0;
}
.page-wraper{
  margin-top: 30px;
  padding-left:20px;
}
</style>


效果展示:

nuxt-link2.gif

编程式导航

在Nuxt中使用内置的navigateTo方法实现编程式导航; 修改Header.vue。

components/Header.vue

<template>
  <div style="width: 100%">
    <nav>
      <a href="javascript:void(0)"  @click="toPath('/')" :class="{ 'router-link-active': currPath === '/'}">首页</a>
      <a href="javascript:void(0)"  @click="toPath('/article/list')" :class="{ 'router-link-active': currPath === '/article/list'}">文章页面</a>
      <a href="javascript:void(0)"  @click="toPath('/news/hot/list')" :class="{ 'router-link-active': currPath === '/news/hot/list'}">热门新闻</a>
      <a href="javascript:void(0)"  @click="toPath('/about')" :class="{ 'router-link-active': currPath === '/about'}">关于我们</a>
    </nav>
  </div>
</template>

<script setup>
const currPath = ref('/')
const toPath = (path) => {
  currPath.value = path
  return navigateTo(path)
}
</script>

<style scoped>
nav{
  display: flex;
  height: 60px;
  box-shadow: 0px 5px 5px rgba(0,0,0, 0.2);
  align-items: center;
}

nav a{
  height: 100%;
  padding: 0 20px;
  text-decoration: none;
  line-height: 60px;
}
nav .router-link-active{
  background: #0f409e;
  color: #fff;
}
</style>

这个时候观察页面和之前一样的效果。编程式导导航能传参数吗,当然是可以的?navigateTo 以对象的方式传入即可,修改下toPath方法:

const toPath = (path) => {
  currPath.value = path
  if (path === '/article/list') {
    return navigateTo({
      path: path,
      query: {
        type: 'article'
      }
    })
  }
  return navigateTo(path)
}

修改pages/article/list.vue

<template>
  <div>
    <p><a href="#">Vue 标题</a></p>
    <p><a href="#">nuxt 标题</a></p>
    <p>接收到参数type: {{ type }}</p>
  </div>
</template>

<script setup>
const type = ref('')
const route = useRoute()

onMounted(() => {
  type.value = route.query.type
})
</script>

<style scoped>

</style>

查看运行结果:

image.png

可以看到我们接收到了参数。

总结

本文主要分析了 pages直接目录下的组件pages 嵌套文件夹下面的组件动态路由可选路由全局路由(针对同一层级)路由视图的嵌套路由导航编程式导航、八种情况下的路由处理。让我对Nuxt有了更进一步的认识。