简介
Next.js 是一个轻量级的 React 服务端渲染应用框架。
官网链接:www.nextjs.cn/
优点:
-
零配置
自动编译并打包。从一开始就为生产环境而优化。
-
混合模式: SSG 和 SSR
在一个项目中同时支持构建时预渲染页面(SSG)和请求时渲染页面(SSR)
-
增量静态生成
在构建之后以增量的方式添加并更新静态预渲染的页面。
-
支持 TypeScript
自动配置并编译 TypeScript。
-
快速刷新
快速、可靠的实时编辑体验,已在 Facebook 级别的应用上规模上得到验证。
-
基于文件系统的路由
每个
pages
目录下的组件都是一条路由。 -
API 路由
创建 API 端点(可选)以提供后端功能。
-
内置支持CSS
使用 CSS 模块创建组件级的样式。内置对 Sass 的支持。
-
代码拆分和打包
采用由 Google Chrome 小组创建的、并经过优化的打包和拆分算法。
创建Next.js项目
手动创建Next.js项目
mkdir nextDemo //创建项目
npm init //初始化项目
npm i react react-dom next --save //添加依赖
在package.json
中添加快捷键命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev" : "next" ,
"build" : " next build",
"start" : "next start"
},
复制代码
创建pages
文件夹和文件
在项目根目录创建pages
文件夹并在pages
文件夹中创建index.js
文件
function Index(){
return (
<div>Hello Next.js</div>
)
}
export default Index
复制代码
运行项目
npm run dev
creact-next-app
快速创建项目
create-next-app
可以快速的创建Next.js
项目,它就是一个脚手架。
npm install -g create-next-app //全局安装脚手架
create-next-app nextDemo //基于脚手架创建项目
cd nextDemo
npm run dev //运行项目
目录结构介绍:
- components文件夹: 这里是专门放置自己写的组件的,这里的组件不包括页面,指公用的或者有专门用途的组件。
- node_modules文件夹:Next项目的所有依赖包都在这里,一般我们不会修改和编辑这里的内容。
- pages文件夹:这里是放置页面的,这里边的内容会自动生成路由,并在服务器端渲染,渲染好后进行数据同步。
- static文件夹: 这个是静态文件夹,比如项目需要的图片、图标和静态资源都可以放到这里。
- .gitignore文件: 这个主要是控制git提交和上传文件的,简称就是忽略提交。
- package.json文件:定义了项目所需要的文件和项目的配置信息(名称、版本和许可证),最主要的是使用
npm install
就可以下载项目所需要的所有包。
Pages
在 Next.js 中,一个 page(页面) 就是一个从 .js
、jsx
、.ts
或 .tsx
文件导出(export)的 React 组件 ,这些文件存放在 pages
目录下。每个 page(页面)都使用其文件名作为路由(route)。
如果你创建了一个命名为 pages/about.js
的文件并导出(export)一个如下所示的 React 组件,则可以通过 /about
路径进行访问。
路由
页面跳转一般有两种形式,第一种是利用标签<Link>
,第二种是用js编程的方式进行跳转,也就是利用Router
组件
Link
import React from 'react'
import Link from 'next/link'
const Home = () => (
<>
<div>我是首页</div>
<div><Link href="/pageA"><a>去A页面</a></Link></div>
<div><Link href="/pageB"><a>去B页面</a></Link></div>
</>
)
export default Home
复制代码
注意:用<Link>
标签进行跳转是非常容易的,但是又一个小坑需要你注意一下,就是他不支持兄弟标签并列的情况。
//错误写法
<div>
<Link href="/pageA">
<span>去A页面</span>
<span>前端博客</span>
</Link>
</div>
//正确写法
<Link href="/pageA">
<a>
<span>去A页面</span>
<span>前端博客</span>
</a>
</Link>
复制代码
Router
import Router from 'next/router'
<button onClick={()=>{Router.push('/pageA')}}>去A页面</button>
复制代码
参数传递与接收
在Next.js
中只能通过通过query(?id=1
)来传递参数,而不能通过(path:id
)的形式传递参数。
import Link from 'next/link'
//传递
<Link href="/blogDetail?bid=23"><a>{blog.title}</a></Link>
//blog.js
import { withRouter} from 'next/router'
import Link from 'next/link'
const BlogDetail = ({router})=>{
return (
<>
<div>blog id: {router.query.name}</div>
<Link href="/"><a>返回首页</a></Link>
</>
)
}
//withRouter是Next.js框架的高级组件,用来处理路由用的
export default withRouter(BlogDetail)
/************************************************************************************/
import Router from 'next/router'
<button onClick={gotoBlogDetail} >博客详情</button>
function gotoBlogDetail(){
Router.push('/blogDetail?bid=23')
}
//object 形式
function gotoBlogDetail(){
Router.push({
pathname:"/blogDetail",
query:{
bid:23
}
})
}
<Link href={{pathname:'/blogDetail',query:{bid:23}}><a>博客详情</a></Link>
复制代码
动态路由
pages/post/[pid].js
route : /post/abc --> query : { "pid": "abc" }
pages/post/[pid]/[comment].js
route : /post/abc/a-comment --> query : { "pid": "abc", "comment": "a-comment" }
复制代码
钩子事件
利用钩子事件是可以作很多事情的,比如转换时的加载动画,关掉页面的一些资源计数器.....
//路由发生变化时
Router.events.on('routeChangeStart',(...args)=>{
console.log('1.routeChangeStart->路由开始变化,参数为:',...args)
})
//路由结束变化时
Router.events.on('routeChangeComplete',(...args)=>{
console.log('routeChangeComplete->路由结束变化,参数为:',...args)
})
//浏览器 history触发前
Router.events.on('beforeHistoryChange',(...args)=>{
console.log('3,beforeHistoryChange->在改变浏览器 history之前触发,参数为:',...args)
})
//路由跳转发生错误时
Router.events.on('routeChangeError',(...args)=>{
console.log('4,routeChangeError->跳转发生错误,参数为:',...args)
})
/****************************hash路由***********************************/
Router.events.on('hashChangeStart',(...args)=>{
console.log('5,hashChangeStart->hash跳转开始时执行,参数为:',...args)
})
Router.events.on('hashChangeComplete',(...args)=>{
console.log('6,hashChangeComplete->hash跳转完成时,参数为:',...args)
})
复制代码
获取数据
getStaticProps
构建时请求数据
在build阶段将页面构建成静态的html文件,这样线上直接访问HTML文件,性能极高。
- 使用
getStaticProps
方法在build阶段返回页面所需的数据。 - 如果是动态路由的页面,使用
getStaticPaths
方法来返回所有的路由参数,以及是否需要回落机制。
// posts will be populated at build time by getStaticProps()
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li>{post.title}</li>
))}
</ul>
)
}
// This function gets called at build time on server-side.
// It won't be called on client-side, so you can even do
// direct database queries. See the "Technical details" section.
export async function getStaticProps(context) {
// Call an external API endpoint to get posts.
// You can use any data fetching library
const res = await fetch('https://.../posts')
const posts = await res.json()
// By returning { props: { posts } }, the Blog component
// will receive `posts` as a prop at build time
return {
props: {
posts,
},
}
}
export default Blog
复制代码
getServerSideProps
每次访问时请求数据
页面中export
一个async
的getServerSideProps
方法,next就会在每次请求时候在服务端调用这个方法。
- 方法只会在服务端运行,每次请求都运行一边
getServerSideProps
方法 - 如果页面通过浏览器端
Link
组件导航而来,Next会向服务端发一个请求,然后在服务端运行getServerSideProps
方法,然后返回JSON到浏览器。
function Page({ data }) {
// Render data...
}
// This gets called on every request
export async function getServerSideProps(context) {
// Fetch data from external API
const res = await fetch(`https://.../data`)
const data = await res.json()
// Pass data to the page via props
return { props: { data } }
}
export default Page
复制代码
CSS支持
添加全局样式表
要将样式表添加到您的应用程序中,请在 pages/_app.js
文件中导入(import)CSS 文件。
在生产环境中,所有 CSS 文件将自动合并为一个经过精简的 .css
文件。
你应该 只在 pages/_app.js
文件中导入(import)样式表。
从 Next.js 9.5.4 版本开始,你可以在应用程序中的任何位置从 node_modules
目录导入(import) CSS 文件了。
对于导入第三方组件所需的 CSS,可以在组件中进行。
添加组件级CSS
-
[name].module.css
//login.module.css .loginDiv{ color: red; } //修改第三方样式 .loginDiv :global(.active){ color:rgb(30, 144, 255) !important; } 复制代码
import styles from './login.module.css' <div className={styles.loginDiv}/> 复制代码
Next.js 允许你导入(import)具有
.scss
和.sass
扩展名的 Sass 文件。 你可以通过 CSS 模块以及.module.scss
或.module.sass
扩展名来使用组件及的 Sassnpm i sass --save
如果要配置 Sass 编译器,可以使用
next.config.js
文件中的sassOptions
参数进行配置。const path = require('path') module.exports = { sassOptions: { includePaths: [path.join(__dirname, 'styles')], }, } 复制代码
-
CSS-in-JS
可以使用任何现有的 CSS-in-JS 解决方案。 最简单的一种是内联样式:
<p style={{ color: 'red' }}>hi there</p> 复制代码
使用
styled-jsx
的组件就像这样function HelloWorld() { return ( <div> Hello world <p>scoped!</p> <style jsx>{` p { color: blue; } div { background: red; } @media (max-width: 600px) { div { background: blue; } } `}</style> <style global jsx>{` body { background: black; } `}</style> </div> ) } export default HelloWorld 复制代码
自定义Header
<Head>
<title>我是最胖的!</title>
<meta charSet='utf-8' />
</Head>
网友评论