提及 服务端渲染(ssr) 和 SPA,相信你总能说个一二:css
这二者的优缺点都很明显,因此随着时代的进步和技术的演变,诞生了 SSR + SPA 的新模式。而且在 react/vue
等前端框架相结合 node (ssr)
下,能够最大限度的重用代码(同构),减小开发维护成本。html
web 应用能够分为 浏览器端 和 服务器端 两部分,对于同构应用来讲,分为 初次发送请求( SSR ) 和 后续操做( SPA )。前端
基于 React 能够在服务端渲染的能力,Next 提供了一套完整且方便的同构应用解决方案。vue
Next.js,这是一个 React 的同构应用开发框架。node
咱们用 CLI 工具 -- Create Next App 来快速建立 Next.js 应用,经过配置参数 -e, --example [name]|[github-url]
能够直接以 Next.js Repo中的模版建立应用:react
npx create-next-app nextjs-auth0 --example "https://github.com/vercel/next.js/tree/master/examples/auth0"
复制代码
咱们今天使用 Next.js 的入门模版(默认):git
npx create-next-app my-nextjs
复制代码
运行成功后,进入 my-nextjs
目录,运行启动命令,应用默认运行在 3000 端口:github
cd my-nextjs
npm run dev
复制代码
http://localhost:3000/, 查看页面源代码,能够发现全部的内容都是服务器端返回的: web
Next.js 在开发时遵循了必定的约定:npm
pages
目录下,页面做为一个组件。pages/index.js
关联的路由是 /
pages/posts/first-post.js
关联的路由是 /posts/first-post
page
具备静态方法 getInitialProps
,能够获取接口数据做为组件的 props
。page/index.js
已经存在,咱们新建一个 pages/posts/first-post.js
:
export default function FirstPost() {
return <h1>First Post</h1>;
}
复制代码
这时候,你访问 http://localhost:3000/posts/first-post
, 应该能够看到:
<Link>
组件能够在客户端实现页面间的导航,和 React Router 同样实现的是前端路由,不会引发页面的刷新:
import Link from "next/link";
复制代码
使用时,将 Link 包裹在 a 标签外,好比在 posts/first-post
添加一个回首页的连接:
import Link from "next/link";
export default function FirstPost() {
return (
<> <h1>First Post</h1> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
);
}
复制代码
Link
组件默认在后台预取目标页面。 经过设置 prefetch={false}
(默认为 true
) 能够禁止页面预取。当 prefetch
被设置为 false
时,鼠标悬停在 上时仍然会触发预取。预取功能只在生产环境中开启。
<Link href="/posts/first-post" prefetch={false}>
<FirstPost />
</Link>
复制代码
Link
组件的默认行为是将新 URL
推送到 history
堆栈中,可使用 replace
来替换 URL,而不是新增,这样发生跳转后,将没法后退到上一个页面。
<Link href="/about" replace>
<a>About us</a>
</Link>
复制代码
Next.js 支持具备动态路由的 pages(页面)。例如,若是你建立了一个命名为 pages/posts/[id].js
的文件,那么就能够经过 posts/1
、posts/2
等相似的路径进行访问。
若是你添加了一张图片到 public/me.png
路径,经过 /me.png
能够直接访问到它:
import Image from "next/image";
function Avatar() {
return <Image src="/me.png" alt="me" width="64" height="64" />;
}
export default Avatar;
复制代码
public
目录映射静态文件,包括 robots.txt
、favicon.ico
、Google 站点验证文件以及任何其它静态文件(包括 .html
文件)。
注意:
- 请勿为 public 更名。此名称是写死的,不能修改,而且只有此目录能过够存放静态资源并对外提供访问。
- 请确保静态文件中没有与
pages/
目录下的文件重名的,不然这将致使错误。
动态加载(Lazy loading)是一种仅在资源须要时加载它们的策略。Next.js 也提供了 import dynamic from "next/dynamic"
帮助咱们实现动态加载策略。
普通 import 一个组件:
import Link from "next/link";
import Hello from "../../component/Hello";
export default function FirstPost() {
return (
<> <h1>First Post</h1> <Hello /> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
);
}
复制代码
动态加载一个组件:
import Link from "next/link";
import dynamic from "next/dynamic";
// import Hello from "../../component/Hello";
const DynamicComponent = dynamic(() => import("../../component/Hello"));
export default function FirstPost() {
return (
<> <h1>First Post</h1> <DynamicComponent /> <h2> <Link href="/"> <a>Back to home</a> </Link> </h2> </>
);
}
复制代码
从 network 能够看出,动态加载的状况下,Hello 组件被做为了单独资源: