next.js
<p>参考:https://nextjs.org/learn/foundations/from-react-to-nextjs/getting-started-with-nextjs</p><p>next.js是react的一个前端框架。react本质上是一个UI库,用于操作虚拟DOM。next.js是基于react的一个前端框架,类似于springboot,有很多约定俗成的配置。</p>
<h3>1 不用脚手架创建next.js项目</h3>
<p>在一个空路径下面创建package.json,内容如下</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
}</span></pre>
</div>
<p>执行命令: <span class="cnblogs_code">npm install react react-dom next</span> </p>
<p>然后,我么再查看package.json</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span>"dependencies"<span style="color: rgba(0, 0, 0, 1)">: {
</span>"next": "^12.1.2"<span style="color: rgba(0, 0, 0, 1)">,
</span>"react": "^18.0.0"<span style="color: rgba(0, 0, 0, 1)">,
</span>"react-dom": "^18.0.0"<span style="color: rgba(0, 0, 0, 1)">
}
}</span></pre>
</div>
<p>同时目录下多了node_modules文件夹,为下载的依赖</p>
<p>创建pages/index.js</p>
<div class="cnblogs_code">
<pre>import { useState } from 'react'
<span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> Header({ title }) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <h1>{title ? title : 'Default title'}</h1>
<span style="color: rgba(0, 0, 0, 1)">}
export </span><span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> HomePage() {
const names </span>= ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'<span style="color: rgba(0, 0, 0, 1)">]
const </span>= useState(0<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> handleClick() {
setLikes(likes </span>+ 1<span style="color: rgba(0, 0, 0, 1)">)
}
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
</span><div>
<Header title="Develop. Preview. Ship. 🚀" />
<ul><span style="color: rgba(0, 0, 0, 1)">
{names.map(name </span>=><span style="color: rgba(0, 0, 0, 1)"> (
</span><li key={name}>{name}</li>
<span style="color: rgba(0, 0, 0, 1)"> ))}
</span></ul>
<button onClick={handleClick}>Like ({likes})</button>
</div>
<span style="color: rgba(0, 0, 0, 1)">)
}</span></pre>
</div>
<p>package.json中添加</p>
<div class="cnblogs_code">
<pre> "scripts"<span style="color: rgba(0, 0, 0, 1)">: {
</span>"dev": "next dev"<span style="color: rgba(0, 0, 0, 1)">
},</span></pre>
</div>
<p>启动</p>
<p> <span class="cnblogs_code">npm run dev</span> </p>
<p>这样,一个简单的next.js项目就搭建好了。</p>
<h3>2 Next.js是如何工作的</h3>
<p>Next.js是一个react框架,包含了很多内置的功能和工具:打包工具webpacked,jsx编译工具Babel,自动代码分割,客户端渲染和服务端渲染,直观的基于页面的路由系统,代码的预加载,高效的开发工具等。</p>
<p>1 开发环境和生产环境<br>next.js框架,提供了适用于开发和生产的命令<br>next dev用于在开发模式下启动项目,会在项目路径下生成.next文件夹。它附带了一些旨在改善开发者体验的特性,比如TypeScript和ESLint的集成、快速刷新等等<br>在生产部署时,Next.js为最终用户以及他们使用应用程序的体验进行优化。它的目的是转换代码,使其高效和可访问<br>2 编译<br>使用JSX、TypeScript和现代版本的JavaScript开发的源代码浏览器是不支持他们的,所以首先要编译成浏览器支持的特定版本的JavaScript。<br>在Next.js中,编译发生在编辑代码的开发阶段,并作为生产环境构建的其中一个步骤。这也是为什么我们修改了代码之后,页面实时更新的原因<br>3 最小化代码规模<br>我们写的源码包含运行代码所不需要的额外信息,如注释、空格、缩进和多行等,但是这些信息其实是不需要的,在Next.js中,JavaScript和CSS文件会被自动压缩。<br>4 绑定<br>我们在开发应用程序时,会把应用程序分解为模块、组件和函数。我们会在源文件中导出和导入这些模块,以及第三方包中的模块。<br>绑定是解析文件间的依赖关系并将文件(或模块)进行合并的过程,目的是减少用户访问网页时对文件的请求数量。<br>5 代码分割<br>上面我们对代码进行了绑定,但是bundle.js是一个比较大的文件。很多情况下,页面上点击某个链接只会加载某个页面,因此对bundle.js进行适当地分割会比较好。Next.js内置了对代码分割的支持。在构建过程中,pages/目录中的每个文件都将被自动分割成一个chunk.js。</p>
<p>编译阶段,项目会被编译为一些文件:<br>1 静态html文件<br>2 用于服务端渲染页面的js<br>3 用于客户端交互的js<br>4 css文件</p>
<p>6 渲染<br>next.js提供了3种渲染方式<br>服务端渲染,<br>客户端渲染,在完成渲染工作之前,用户将看到一个空白页面<br>生成静态页面</p>
<p><img src="https://img2022.cnblogs.com/blog/2329252/202204/2329252-20220407095503904-650745487.png"></p>
<p> </p>
<p> <img src="https://img2022.cnblogs.com/blog/2329252/202204/2329252-20220407095531552-1183783148.png"></p>
<p> </p>
<p> </p>
<p>Next.js默认情况下会预渲染每个页面。预渲染意味着HTML是提前在服务器上生成的,而不是由JavaScript在用户的设备上完成。</p>
<p>7 路由</p>
<p>在next中,pages目录下的组件就是一个页面<br>路由默认是pages下的文件名:比如路由"/"对应pages/index.js,路由"/posts/first-post"对应pages/posts/first-post.js</p>
<p>在pages下创建posts目录,然后创建first-post.js<br>export default function FirstPost() {<br>return <h1>First Post</h1><br>}<br>页面访问http://localhost:3000/posts/first-post,我们会发现,不需要额外的路由配置,默认路由起作用了。</p>
<p>8 代码预加载</p>
<p>对于Next中定义的一些组件(比如Link),Next.js会在空闲时间预加载组件(预先请求href,返回数据),这样当我们点击Link的时候,页面反应是瞬时的。</p>
<div class="cnblogs_code">
<pre> <Link href="/">
<a>Back to home</a>
</Link></pre>
</div>
<p>9 惰性加载</p>
<p>在Next.js中定义的一些组件(比如Image组件)是惰性加载的。</p>
<div class="cnblogs_code">
<pre><<span style="color: rgba(0, 0, 0, 1)">Image
src</span>="/images/profile.jpg" <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Route of the image file</span>
height={144} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Desired size with correct aspect ratio</span>
width={144} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> Desired size with correct aspect ratio</span>
alt="szj"
/></pre>
</div>
<p>next/image是对img标签的替换。<br>默认情况下,图片是惰性加载的。这意味着您的页面速度不会因viewport外的图像而受到影响。图像被滚动到viewport中时才加载</p>
<h3>3 使用脚手架创建Next.js项目</h3>
<p> <span class="cnblogs_code">npx create-next-app nextjs-blog --use-npm --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"</span> </p>
<h3> 4 再谈Next.js的服务端预渲染</h3>
<p>默认情况下,Next.js预渲染每个页面。这意味着Next.js提前为每个页面生成HTML,而不是全部由客户端JavaScript完成。预渲染可以带来更好的性能和SEO。</p>
<p>每个生成的HTML都与该页面所需的最小JavaScript代码相关联。当页面被浏览器加载时,它的JavaScript代码运行并和UI交互。</p>
<p>如果你的应用是一个普通的React.js应用(没有Next.js),没有预渲染,当打开页面时,我们将会看到如下提示“Sorry, we need js to run correctly!”,并且我们查看response,我们发现我们只得到一个空的div。</p>
<p> <span class="cnblogs_code"><noscript>Sorry, we need js to run correctly!</noscript><div id="root"></div><script src="/umi.js"></script></span> </p>
<p>正如我们前面提到过的,React项目只会返回一个空的UI。页面DOM的操作是React在客户端电脑上通过虚拟DOM实现的。</p>
<p><img src="https://img2022.cnblogs.com/blog/2329252/202204/2329252-20220407105632517-494781311.png"></p>
<p> </p>
<p> Next.js有两种形式的预渲染:编译时生成静态html,每次请求时生成html。即静态页面和服务端预渲染</p>
<p><img src="https://img2022.cnblogs.com/blog/2329252/202204/2329252-20220407110149199-294451455.png"></p>
<p> </p>
<p> 我么可以选择使用哪种预渲染策略。比如页面一我么使用静态页面策略,页面二我们使用服务端预渲染。具体该使用何种预渲染策略,需要根据实际情况确定,如果页面数据频繁的更新,则我们使用服务端渲染,如果是一些历史订单等信息,我们使用静态页面策略。</p>
<h4>4.1 getStaticProps<code class="jsx-d60897d45df4a3d0"></code></h4>
<p>有时,我们希望页面在编译时就编译为静态html,后面请求该页面都请求静态页面。但是这个页面数据需要从后台获取。这时我们就需要getStaticProps。做法是在这个页面中export一个async的函数getStaticProps。其工作原理是:</p>
<ul>
<li><code class="jsx-d60897d45df4a3d0">getStaticProps</code> 函数在编译时运行…</li>
<li>并且在该函数中请求后台数据,数据以props的形式传递给当前页面</li>
</ul>
<p>示例:</p>
<h4>4.2 getServerSideProps</h4>
<p>如果我们希望服务端渲染,而且希望每次请求都获取后端数据,而不是在编译时获取后端数据,则我们使用getServerSideProps。</p>
<p><img src="https://img2022.cnblogs.com/blog/2329252/202204/2329252-20220408112738799-1725741461.png"></p>
<p> </p>
<p> </p>
<div class="cnblogs_code">
<pre>export async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getServerSideProps(context) {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
props: {
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> props for your component</span>
<span style="color: rgba(0, 0, 0, 1)"> }
}
}</span></pre>
</div>
<h3> 5 动态路由</h3>
<p>要实现动态路由,主要两个步骤:</p>
<p>1 创建.js</p>
<p>2 .js中写getStaticPaths函数</p>
<div class="cnblogs_code">
<pre>export async <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> getStaticPaths() {
</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ...这里从后台获取路由数据
}</span></pre>
</div>
<p> </p>
<p><img src="https://img2022.cnblogs.com/blog/2329252/202204/2329252-20220408142226501-1763629025.png"></p>
<p> </p>
<p> </p>
<p> </p>
<h3> 6 API路由</h3>
<p>API路由其功能类似于后端写的API接口,可以理解为,Next.js替代了部分后端该做的事,或者分担后端的一些工作</p>
<p>API路由都在pages/api/路径下,比如,我们再pages/api下创建hello.js</p>
<div class="cnblogs_code">
<pre>export <span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> handler(req, res) {
res.status(</span>200).json({ text: 'Hello'<span style="color: rgba(0, 0, 0, 1)"> })
}</span></pre>
</div>
<p>其有两个参数req和res,返回一个json,我们访问http://localhost:3000/api/hello,将得到一个json数据</p>
<p> <span class="cnblogs_code">{"text":"Hello"}</span> </p>
<p> </p><br><br>
来源:https://www.cnblogs.com/zhenjingcool/p/16079882.html
頁:
[1]