目前nuxt3还是beta版本,先浅学一下吧
bug我感觉还是有点多的,如果遇到任何问题,尝试重新启动一下项目可能有奇效😢
npx nuxi init Project-name
👇
cd Project-name
👇
npm i
一些常用的目录,自己建:
如果pages文件夹里没东西,要删除这个文件夹,不然会404
第一个页面建立好之后,如何访问这个页面?
在app.vue
中使用
标签,这相当于路由的出口
比如现在pages
文件夹中有一个index.vue
,想要访问它,无需配置路由
<template>
<div>
<nuxt-page>nuxt-page>
div>
template>
然后在地址栏访问时:http://localhost:3000
,就行啦
⚠️:因为index
是默认的入口,如果你取名叫about.vue
,访问时要输入http://localhost:3000/about
nuxt
不鼓励用标签进行跳转,而是使用
标签
比如要从index.vue
页面跳转到about.vue
页面:
<template>
<div>
<h1>indexh1>
<nuxt-link to="/about">to aboutnuxt-link>
div>
template>
参数写在页面的文件名里,并且用[]
扩起来
比如新建一个页面叫detail-[id].vue
这里传递的参数就是id
--| pages
--| index.vue
--| detail-[id].vue
参数接收在模板中可以使用$route.params.id
<template>
<div>id: {{ $route.params.id }}div>
template>
在index.vue
中写一个跳转链接:
<template>
<div>
<nuxt-link to="/detail-20">to detailnuxt-link>
div>
template>
⚠️:在index.vue
中要用一个元素作为根元素!!
不然可能会出现路由已经跳转了但是页面没变化,要刷新才有变化的bug
如果要传递两个参数,需要建一个文件夹,在文件夹名上使用[]
来确定参数
比如要传递一个name
参数和id
参数
--| pages
--| detail-[name]
--| [id].vue
修改index.vue
:
<template>
<div>
<nuxt-link to="/detail-poem/20">to detailnuxt-link>
div>
template>
在script
获取:
<template>
<div>
<div>获取的id:{{ id }}div>
<div>获取的name:{{ name }}div>
div>
template>
<script setup>
import { ref } from "vue";
const route = useRoute();
const id = ref(route.params.id); // 20
const name = ref(route.params.name); // poem
script>
建立一个嵌套路由页面:
parent.vue
parent
parent/child.vue
--| pages
--| parent
--| child.vue
--| index.vue
--| parent.vue
编写parent.vue
:
是子路由的出口
<template>
<div>
<div>parent pagediv>
<nuxt-child>nuxt-child>
div>
template>
在index.vue
中写跳转链接:
<template>
<div>
<div>indexdiv>
<nuxt-link to="/parent/child">to parent/childnuxt-link>
<nuxt-link to="/parent">to parent/indexnuxt-link>
div>
template>
将通用的ui代码提取到一个模板中
布局模板约定都放在layouts
文件夹下
layouts/default.vue
用于指定默认布局
作为插槽
<template>
<div>我是默认的布局模板div>
<slot>slot>
template>
页面使用布局模板:
使用
标签引用模板
<template>
<nuxt-layout>nuxt-layout>
<div>demodiv>
template>
如何添加多个插槽:
修改default.vue
布局模板,给插槽加上name
<template>
<div>
<div>我是默认的布局模板div>
<slot name="header">slot>
<slot name="footer">slot>
div>
template>
在页面中通过的形式来指定对应的插槽:
注意要放在
里
<template>
<nuxt-layout>
<template #header>
<div>headerdiv>
template>
<template #footer>
<div>footerdiv>
template>
nuxt-layout>
<div>demodiv>
template>
记得👆创建的是default.vue
,这个是默认布局
自定义布局其实就是在layouts
目录下建其他名字的文件
这里创建一个layouts/blog.vue
blog.vue
的编写和default.vue
是一样的
<template>
<div>我是一个博客的布局模板div>
<slot>slot>
template>
在页面中使用时就有些小变化:
还是使用
标签引用模板
但要多写一个name
属性说清楚名字,如果是default.vue
的话就不用写name
,默认为name="default"
<template>
<nuxt-layout name="blog">nuxt-layout>
<div>demodiv>
template>
组件约定写在components
目录下
写在这个目录下它会自动加载到页面中,不需要import
组件不止可以用在页面中,也可以用在布局模板中!!
写法跟之前是一样的,这里就不放例子了😢
如果组件不是放在components
目录的顶层
例如:
--| components
--| base
--| MyButton.vue
在页面中使用时:
组件的名称将基于自己的路径目录和文件名
<template>
<div>
<base-my-button>base-my-button>
div>
template>
要实现按需懒加载组件,只要在组件名前面加上Lazy
前缀就可以了
懒加载组件就是只有当组件需要用到时才加载,减少页面加载需要的时间
当我们需要一个组件时而显示时而不显示的时候,使用懒加载就很有用了
--| components
--| LazyText.vue
<template>
<div>
<lazy-text v-if="isShow">lazy-text>
<button @click="handleClick">显示/隐藏button>
div>
template>
<script setup>
import { ref } from "vue"
const isShow = ref(false)
const handleClick = () => {
isShow.value = !isShow.value
}
script>
一些通用的业务逻辑代码,可以放在composables
文件夹中
比如获取当前时间的函数:
--| composables
--| getTime.ts
// getTime.ts 这里细节略过
export const getTime = () => {
// ...
console.log('get time successfully!')
}
在组件或者页面中就可以直接使用,不需要导入
<script setup>
getTime();
script>
但是注意这个composables
目录名是不能变的,取别的名字可能就是需要自己引入了
composables
的引入规则是只有顶层文件会被引入
比如你又用了一个test文件夹来包裹代码
--| composables
--| test
--| getTime.vue
这时候直接使用getTime()
会报错
解决方法是:在test
目录下新建一个index.ts
,然后将getTime.ts
中的内容导入index.ts
再导出
import { getTime } from './getTime'
export {
getTime
}
这样就可以跟上面一样在组件和页面中正常使用getTime()
useAsyncData()
useFetch()
useAsyncData(key, handler, options)
第一个参数是一个唯一的键,相当于是这个请求的名字,相当于是起了一个id
第二个参数是有返回值的异步函数,$fetch
是nuxt3的内置方法可以直接用,这里要传一个请求url
第三个参数是可选的配置项,比如可以传{lazy: true}
来决定开启懒加载
还有一些配置项,需要的话可以看官网:https://v3.nuxtjs.org/api/composables/use-async-data
<script setup>
const res = await useAsyncData("getList", () => $fetch(url));
script>
算是useAsyncData()
的简化版
第一个参数传请求url
第二个参数是可选的配置项
https://v3.nuxtjs.org/api/composables/use-fetch
<script setup>
const res = await useFetch(url);
script>
nuxt
提供了一个可定制的路由中间件框架
目的是在导航到特定路由之前执行一些代码
路由中间件分三种:
匿名
路由中间件,在使用它们的页面中定义命名
路由中间件,放在middleware
目录下,页面使用时会自动加载全局
路由中间件,放在middleware
目录下,且带.global
后缀,每次路由更改都会自动执行新建一个middleware
文件夹,文件下新建一个default.global.ts
文件
export default defineNuxtRouteMiddleware((to, from) => {
if(to.path === '/demo') {
console.log('禁止访问')
// 终止导航
return abortNavigation()
}
// 重定向到pages/index.vue
return navigateTo('/')
})
nuxt提供了两个全局的helper,可以直接在中间件被返回
navigateTo()
:重定向到给定的路由abortNavigation()
:终止导航这个就不是全局的了
新建一个middleware
文件夹,文件下新建一个default.ts
文件
export default defineNuxtRouteMiddleware((to,from) => {
console.log(1)
})
在你要使用的页面中:
<script setup>
definePageMeta({
// 可以接收多个路由中间件
middleware: ["default"],
})
script>
命名路由中间件就是只对这个demo页面起作用,对其他的页面是没用的
匿名路由中间件官网没例子 我也不知道咋写555 下次吧
主要是对标签和
标签的设置
标签和seo相关的主要是
name=description
和name=keywords
这两种
如果不设置这两种标签,对seo的效果会有影响
<script setup>
useHead({
title: "poem的博客",
viewport: "width=device-width,initial-scale=1,maximum-scale=1",
charset: "utf-8",
meta: [
{ name: "description", content: "poem的博客" },
{ name: "keywords", content: "poem,博客" },
],
})
script>
现在跳到demo页就会显示我们设置的head了
这里面的内容可以动态绑定
注意、
、要首字母大写
<template>
<div>
<Head>
<Title>poem的博客Title>
<Meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1">Meta>
<Meta name="description" content="poem的博客" />
<Meta name="keywords" content="poem,博客" />
Head>
div>
template>
还是得回去学一下nuxt2 555😢
参考:
https://v3.nuxtjs.org/guide/concepts/introduction
https://jspang.com/article/86#toc1