视频教程 nuxt3教程 2024年7月哔哩哔哩bilibili
路由
路由的基本使用
在nuxt
中不需要创建路由,nuxt
对vue-router
进行了封装,直接创建pages
文件夹就可以,这个文件夹中的每一个文件都会变成一个路由
在根目录创建pages
文件夹,里面创建index.vue
和about.vue
文件
直接在地址来修改路径,在虎爷地址后面添加文件名进行访问,发现页面没有变化
原因是需要去掉根目录下面的
app.vue
文件才可以 或者在app.vue
文件中添加一个入口
xml
<script setup></script>
<template>
<header>头部</header>
<main>
<router-view></router-view>
</main>
<footer>尾部</footer>
</template>
<style scoped lang="scss">
header,
footer,
main {
border: 1px solid #ccc;
}
</style>
index.vue
的路由就是一个/
,也就是主页
页面入口我们可以直接使用router-view
标签,也可以使用nuxt
中的NuxtPage
,一般是使用NuxtPage
,NuxtPage
功能是router-view
一样,但是更强大,支持命名路由和可选路由
在vue
中使用router-link
进行跳转页面,在nuxt
中使用NuxtLink
切换页面的时候是在
客户端
进行渲染的,刷新之后才是在服务端渲染
命名路由
命名路由是根据名字进行创建路由
在pages
下面创建一个user
文件夹,然后创建一个文件,文件名是[名称].vue
类似于vue
中的动态路由/user/:名称
访问地址和vue
中一样http://localhost:3000/user/aa
其中aa
可以是任意字符,叫做命名路由的参数,一般情况是id
,不能为空
xml
<script setup lang="ts">
// 获取传递的参数
const route = useRoute();
console.log("route", route.params.aa);
</script>
<template>
<div>路由</div>
</template>
<style lang="scss"></style>
在vue中定义动态路由:
css{ path:"/user/:id", component: () => import("../user/userInfo.vue"), }
表示当访问
项目主页
+/user/参数
是访问的是userInfo.vue
文件在
nuxt
中不需要在创建路由表,需要动态路由的时候,直接创建一个[id].vue
就可以了,访问方式和vue
一样,访问的文件就是创建的这个文件
可选路由
在pages
文件加下面创建[[test]]
文件夹,在文件夹下面创建test.vue
文件
访问地址是localhost:3000/aaa/test
aaa
是任意字符,可以去掉 ,获取方式和命名路由
一样test
是创建的文件
类似于
vue
中的动态路由,例如:
css{ path:"/user/:id/info", component: () => import("../user/userInfo.vue"), }
相当于是将
vue
的动态路由拆成了命名路由和可选路由问题:如果创建一个动态路由+可选路由,是否就没有
404
页面了?答案:不会的,当层级多了还是会出现404页面,例如只创建了一层可选路由和动态路由,那么
localhost:3000/api/test/aaa
不满足所有的路由就会走404
,也就是后面的全局路由
全局路由
nuxt
中定了一个全局路由,在/pages
根目录下麦呢创建一个[...名称].vue
文件,当所有的路由都没有匹配到的时候就会走到全局路由
相当于vue
中的404
路由
自定义路由
默认情况下是通过文件名形成路由,也可以通过definePageMeta
自行设置路由名
xml
<script setup lang="ts">
definePageMeta({
path:"/about1"
})
</script>
<template>
<div>about</div>
</template>
<style lang="scss">
</style>
嵌套路由
如果需要创建路由嵌套,那么需要再/pages
文件夹下面创建info.vue
和info
文件夹,然后在info
文件夹下面创建多个文件
arduino
pages
├── about.vue # http://localhost:3000/about
├── index.vue # http://localhost:3000/
├── info
│ ├── aa.vue # http://localhost:3000/info/aa
│ ├── index.vue # http://localhost:3000/info/
│ └── one.vue # http://localhost:3000/info/one
├── info.vue # http://localhost:3000/info
├── [[bb]]
│ └── [ccc].vue # http://localhost:3000/随意字符或者空/随意字符 如果有能匹配到的就不执行这个
├── user
│ └── [aa].vue # http://localhost:3000/user/随意字符
├── [...500].vue # 所有路由没有匹配时
└── [[test]]
└── test.vue # http://localhost:3000/随意字符或者空/user
在执行子路由的时候,也会执行副路由里面的代码
编程式navigateTo
在vue
中编程式路由是:
phpconst router = useRouter() router.push({ path: '/about' })
router.push
只能在客户端使用navigateTo
在客户端和服务端都能使用
xml
<!-- \pages\index.vue -->
<script setup lang="ts">
if (import.meta.server) {
const router = useRouter();
// router.push("/user/aa");
navigateTo('/user/aa')
}
</script>
<template>
<div>
首页
</div>
</template>
执行这个文件会跳转到主页,并不会跳转到/user/aa
将router.push
换成navigateTo
只要一执行就会跳转
navigateTo
不会阻止后面代码执行,如果有打印会在服务端进行打印,客户端不会打印,因为页面已经跳转了,客户端不会在继续渲染
路由中间件
在vue
中是通过beforeEach
定义导航守卫,在nuxt
中是使用中间件的形式存在
中间件值定义在middleware
文件夹中
在根目录创建middleware
文件夹,在文件夹下面创建my.js
javascript
export default defineNuxtRouteMiddleware((to, from) => {
console.log("🚀 ~ defineNuxtRouteMiddleware ~ to:", to.path)
})
在需要使用的页面进行引入
xml
<!-- \pages\index.vue -->
<script setup lang="ts">
definePageMeta({
middleware: [
// 可以存在多个
'my'
]
});
</script>
<template>
<div>首页</div>
</template>
在使用多个中间件的时候,执行顺序是从上往下
如果在中间件中需要跳转页面,在使用navigateTo
前面需要添加return
,在添加return
的时候,如果想要后面的中间件执行,需要return true
也可以直接在页面中定义中间件
xml
<!-- \pages\index.vue -->
<script setup lang="ts">
definePageMeta({
middleware: [
// 中间件
function (to, form) {
console.log("🚀 ~ to:", to);
}
]
});
</script>
<template>
<div>首页</div>
</template>
如果想要定义全局的中间件那么文件名必须是名称.global.js
,定义内容是一样的,不需要在单独引入,全局中间件也可以定义多个,顺序是文件名的 ascii
码排序
导航守卫
导航守卫写在全局中间件中,在导航守卫中一般需要判断本地是否存在token
,而token
是存在于客户端的localStorage
中,但是在服务端是不存在localStorage
的,因此在使用之前需要先判断是否是客户端,只有是客户端的时候才会执行
在书写的时候需要注意是编写的代码是否存在于服务端
在页面中需要一开始执行的代码,如果不需要服务端渲染,需要写在onMounted
中