温州专业微网站制作价格,电影网,请小组讨论一个完整的网页设计流程,wordpress多站点多模板用next.js也有几天了#xff0c;也是这么一个边看边用这么一个状态#xff0c;现在主要使用app router模式#xff0c;更新下next.js v14 app router模式方面的姿势吧。
区别于前面的pages router, app router虽然也是根据目录结构来划分路由#xff0c;但是它不再依赖于使…用next.js也有几天了也是这么一个边看边用这么一个状态现在主要使用app router模式更新下next.js v14 app router模式方面的姿势吧。
区别于前面的pages router, app router虽然也是根据目录结构来划分路由但是它不再依赖于使用getServerSideProps/getStaticProps在服务器时期去获取数据在app router模式下只区分服务器组件和客户端组件且一些在pages路由模式下的方法也无法在app路由下使用。
那现在服务器组件怎么获取数据呢
nextjs app router现在约定的结构是
app 目录名 (即路由名比如名字是home对用的路径是/home)page.ts 当前页面对应的路由layout.ts layout布局组件loading.ts loading加载动画not-found.ts 404页面api restful api文件夹每一个目录下至少需要一个page.ts文件否则访问该路由会报错。而layout布局文件则根据是否需要来创建loading加载文件相当于suspense里的loading也就是加载这个路由前的加载动画Suspense应该是唯一一个能用的react组件了吧在服务器组件里且suspense不需要指定loaidng了not-found 404页面只有app根目录下才需要其他子路由创建无效api文件夹是存放restful api文件的地址同app router,一个文件就是一个路由且同app router的page.tsrestful只认route.ts文件为当前路由文件。
next.js只区分服务器组件和客户端组件服务器组件可以是异步的。所以如果我们需要在服务器组件里获取数据直接await请求就可以了。真的比pages路由里的export function getServerSideProps啥的不要方便太多。比如
import React from react;export default async function Home() {const { data } await fetch(xxx);...return (div...Child result{data} /.../div)
}我们把请求好的数据当成props传给子组件就行了逻辑是与pages的getServerSideProps是一样的 但是一定要小心千万不要在服务器组件里使用任何react的hooks或其他api连组件的合成事件都不行
这里补充下RESTFUL api的使用方法
目录结构
tips: api文件是在app目录下的。
apilogin route.ts // 访问地址是(/api/login)getGamelist route.ts // 访问地址是(/api/getGamelist)...前面说了只有当前目录下的route.ts才会被当成路由文件一个route.ts里可以定义GET/POST/PUT/DELETE等method名称的函数即每个函数对应请求该接口的method属性的接口所以可以根据需求来设计对应的方法。 route.ts文件
import { NextResponse, NextRequest } from next/server;export function Post(req: NextRequest ) {...return NextResponse.json({...}, {status: 200})
}补充2 怎么获取Post请求携带的参数 NextRequest 这个类型是在Web Request api的基础上继承来的(NextResponse也是同理)在Request基础上拓展更多更好使用的属性或方法具体可看文档。所以想要获取post请求里的req.body 我们可以看mdn上Request的说明 其描述携带参数后body是ReadableStream类型那我们获取直接json格式化就可以了注意这是一个异步操作。 例如login下的route.ts是这样的
import { NextResponse, NextRequest } from next/server;export async function Post(req: NextRequest ) {const { token } (await request.json()) as { token?: string };...return NextResponse.json({...}, {status: 200})
}这样我们就能拿到body里传过来的token字段了。 使用则直接fetch/xmlHttpRequest请求/api/login
...
const request new Request(/api/login, {method: post,body: JSON.stringify({ token }),
})
fetch(request).then((res) res.json()).then((res) {...})一些个人使用后的发现
虽然区分服务器组件和客户端组件但是客户端组件不是说一定在浏览器里动态给你渲染出来它也是在服务器里给你渲染好的。真正想要在浏览器里渲染你可以使用动态导入并指明不需要ssr
import dynamic from next/dynamic;const Loading dynamic(() import(/components/loading), { ssr: false });这个Loading组件就不会在服务器时期渲染了。dynamic不止用来延迟加载组件也可以延迟加载库。
动态路由怎么定义同pages路由凡是[xxx]的文件夹都是对应的动态路由。在app router下是不能使用next/router因为它是只为pages路由服务的next.js把路由相关的api封装到了next/navigation里。注意pages路由模式也不能使用next/navigation这是为app router设计的。
那怎么获取路由参数呢
import { useParams } from next/navigation 通过useParams来获取当前的路由参数。 即 const params useParams() 输出这个params就能看到当前所有的路由参数; import { useSearchParams } from next/navigation 来获取location.search参数 usePathname 则是获取当前的路由地址 编程式导航则给到了useRouter这个api跟vue router常用用法基本一致也是啥push/replace/backvue是go 以上几个api都来自next/navigation需要注意的是这几个都是只能在客户端组件内调用,不能用在服务器组件里。 next/navigation里服务器组件能用的api notFound 打开404页面 redirect 重定向到某个页面
其他一些补充server api fetch同样是拓展了Web fetch 方法现在可以指定cache字段来设置缓存时间所以fetch方法不需要额外导入。 next/headers暴露的headersapi可以让你获取请求头里的参数只读。 next/headers暴露的cookies则可以增删改查cookies。怎么用直接看MDN。
next.js内置的组件
Image
image组件是专门用来处理图像的它功能是非常强大的。看文档 它支持懒加载图片支持加载动画可以是 今天先这么多吧 来活了 我要去码 支持占位图动态压缩以及图片加载状态的回调等。 需要注意的是如果加载的是三方的图片资源需要在next.config.js里配置三方地址的host信息否则直接错误。 例如我想要加载img.freepik.com这个网站里的图片资源那我需要先配置remotePatterns next.config.js
const nextConfig {...images: {remotePatterns: [{protocol: https, //协议hostname img.freepik.com, //host地址 }],// 如果为 true则源图像将按原样提供而不是更改质量、大小或格式。默认为falseunoptimized: true,}...
}Link
Next.js用于页面导航的组件实际会渲染成a标签。不过区别于编程式导航Lilnk组件的导航会默认预加载处理。所以为了体验优化之类的尽量多用Link导航。
Script
用于加载script脚本的组件可以配置加载策略strategy 及提供加载状态的回调。
Font
用于加载字体的组件你可以理解成css font-face的封装。它可以加载远程字体以及本地字体 远程字体主要是 google字体通过搜索到对应的字体直接使用即可,用法拉下来的模板里就有加载谷歌字体的示例(在app/layout.ts里)要是没翻墙工具的话把加载google字体的代码注销吧不然可能会运行不起来因为加载不到字体。 如果google字体没有需要用到本地自定义字体的话。
import CunstomFont from next/font/local;const csFont CunstomFont({src: ../assets/fonts/Overlock-Regular.ttf,display: swap,
});
// 在需要自定义字体的地方直接添加样式csFont.className 比如我全局都要那我在body上添加自定义字体的class
...
body className{csFont.className} ... /body具体用法可以参考官方文档 Font
Next.js使用代理请求
如果因为本地开发的时候跨域 想要使用代理来请求next.js也是支持的。 在next.config.js里有个字段是rewrites配置这个字段即可实现代理请求
// 判断环境
const isProd [production].includes(process.env.NODE_ENV);
// 转发
const rewrites () {if (!isProd) {return [{source: /api/:slug*,destination: process.env.NEXT_PUBLIC_BASEURL,},];} else {return [];}
};
const nextConfig {...rewrites,...
}使用直接/api/xxx就行了。 NEXT_PUBLIC_BASEURL 是我配置的环境变量环境变量这里插一嘴。 只有NEXT_PUBLIC前缀的属性能被浏览器环境获取到服务器环境则不限制只要是写在环境变量里的字段都能获取到。
应该没啥要补充的了吧就酱。
middleware中间件
差点把这个忘了中间件可以在请求时拦截或者重定向到其他页面middleware通常位于app目录同级也就是说src/app那么middleware就在src/middleware.ts这里。 middleware需要暴露出两个方法出来一个是
config
export const config {matcher: *
}config.matcher 是匹配的规则一般是正则表达式只有匹配上的才会执行middleware中间件
middleware
import { NextRequest, NextResponse } from next/server;
...
export function middleware(req: NextRequest) {...// 中间的逻辑 比如要重定向到别的页面if (xxx) {return NextResponse.redirect(new URL(/abc, req.url))}...return NextResponse.next();
}只有config.matcher匹配上的请求才会执行middleware