其他分享
首页 > 其他分享> > Next.js

Next.js

作者:互联网

简介:Next.js 是一个轻量级的React服务端渲染框架

 

一. 为什么要使用Next

1.首屏等待

在 SPA 模式下,所有的数据请求和 Dom 渲染都在浏览器端完成,所以当我们第一次访问页面的时候很可能会存在“白屏”等待,而服务端渲染所有数据请求和 html内容已在服务端处理完成,浏览器收到的是完整的 html 内容,可以更快的看到渲染内容,在服务端完成数据请求肯定是要比在浏览器端效率要高的多。

2.SEO的优化

有些网站的流量来源主要还是靠搜索引擎,所以网站的 SEO 还是很重要的,而 SPA 模式对搜索引擎不够友好,要想彻底解决这个问题只能采用服务端直出。

二.优缺点

1.服务端渲染:

1).优点:

前端渲染时间。因为后端拼接html,浏览器只需直接渲染出来。

有利于SEO。服务端有完整的html页面,所以爬虫更容易获得信息,更利于seo

无需占用客户端资源,模板解析由后端完成,客户端只需解析标准的html页面,这样对客户端的资源占用更 少,尤其是移动端,可以更加省电。

后端生成静态化文件。即生成缓存片段,这样就可以减少数据库查询浪费的时间了,且对于数据变化不大的页面非常高效 等。

2).缺点:

不利于前后端分离,开发效率很低。

占用服务器端资源。请求过多对服务器压力很大。

即使局部页面发生变化也需要重新请求整个页面,费流量等。

2.客户端渲染:

1).优点: 

节省后端资源

多端渲染

前后端分离,大大提升开发效率

局部刷新等

三.Next.js是完全属于服务端渲染吗?

既然如此,服务端渲染的优点就是客户端渲染的缺点,服务端渲染的缺点同时也是客户端渲染的优点,反之亦然。看之前不是很理解,由于服务端渲染的各种缺点我们已经告别了服务端渲染的时代,进入了前后端分离的客户端渲染时代,又为什么重新回到了服务端渲染?

了解发现,其实把Next/nust.js成为SSR不是很准确,应该是Isomorphic render(同构渲染),那么什么是同构渲染?

前后端同构是指在前后端维护同一份代码。它是在SPA的基础上,利用服务端渲染(SSR)直出首屏,解除单页面应用(SPA)在首屏渲染上面临的窘境。明确地说,同构是将传统的纯服务端直出的首屏优势和SPA的站内体验优势结合起来,以取得最优解的解决方案。

同构渲染就是实现了ssr和spa两种技术的结合,同时可以最大限度的重用代码(同构),减少开发维护成本,采用 react 或者 vue 等前端框架相结合 node (ssr) 来实现。

四.Next渲染流程

 

         

 

 

Next.js优点:

完善的React项目架构,搭建轻松。 自带数据同步策略,解决服务端渲染最大难点. 配置灵活 丰富的插件帮开发人员增加各种功能。

 

五.创建流程

1.通过creact-next-app快速创建Next.js项目

1).安装creact-next-app

Javascript          
xxxxxxxxxx
      1
npm install -g create-next-app
     

安装完成后,就可以通过create-next-app命令来创建一个Next.js的项目了。

Javascript          
xxxxxxxxxx
      1
npx create-next-app deemo
     

进入项目目录,执行yarn dev。在浏览器中输入http://localhost:3000/,看到下面的内容,说明项目生成成功。

2.目录结构

 

         

 

3.Next.js的Page和Component的使用

1)Page

在pages下新建一个test.js的页面,页面可以随意输入一些内容,这里按照hooks的方式编写你的函数型组件

Javascript          
xxxxxxxxxx
      1
function TestButton(){
2
    return (<button>Test Button</button>)
3
}
4
5
export default  TestButton;
      然后在网页的地址栏中http://localhost:3000/test 然后我们发现,页面上已经显示test.js的页面内容了,这是因为Next框架自动做好了路由,这个也算是Next的一个重要优点。   2)Component  

可以再根目录下创建一个components的文件夹,来存放我们的公用组件。

先来创建一个button的组件,首先在components文件夹下创建button.js文件,然后编辑页面,先按最简单的写法来创建一个按钮。

Javascript          
xxxxxxxxxx
      1
export default ({children})=><button>{children}</button>
     

组件创建完成后,在pages下的index.js页面引入该文件

Javascript          
xxxxxxxxxx
      1
import Button from '../components/button'
     

然后在页面上引入该组件

Javascript          
xxxxxxxxxx
      1
<Button>按钮</Button>
     

 

4.路由-基础和基本跳转

页面跳转一般有两种形式,第一种是利用标签<Link>,第二种是用js编程的方式进行跳转,也就是利用Router组件。

1)标签式导航<Link>

首先引入标签式导航< Link >

Javascript          
xxxxxxxxxx
      1
import Link from 'next/link'
     

跳转刚才的test.js 页面

Javascript          
xxxxxxxxxx
      1
<Link href="/test">Test</Link>
     

注意:<Link>下如果不写内容,或者写多个标签都会报错

Javascript          
xxxxxxxxxx
      1
//不写内容
2
<Link href="/test"></Link>
3
4
//多个标签,可用一个父标签包裹
5
<Link href="/test">
6
   <span>test1</span>
7
   <span>test2</span>
8
 </Link>
     

2)Router

Javascript          
xxxxxxxxxx
      1
import Router from 'next/router'
2
3
...
4
<button onClick={()=>{Router.push('/test')}}前往Test页面</button>
     

 

5.路由-query传参

1).标签式< Link >传参

Javascript          
xxxxxxxxxx
      1
<Link href="/test?id=123">
2
     <span>前往Test页面</span>
3
</Link>
     

或者

Javascript          
xxxxxxxxxx
      1
<Link href={{pathname:'/test',query:{id:'123'}}}>
2
    <span>前往Test页面</span>
3
</Link>
     

2).Router导航传参

Javascript          
xxxxxxxxxx
      1
<button onClick={()=>{Router.push('/test?id=123')}}>前往Test页面</button>
     

或者

Javascript          
xxxxxxxxxx
      1
<button onClick={()=>{Router.push({pathname:'/test',query:{id:'123'}})}}>前往Test页面</button>
     

 

6.路由-接收参数

使用withRouter, 它是Next.js框架的高阶组件,用来处理路由的。(高阶组件)

Javascript          
xxxxxxxxxx
        1
// 引入withRouter
2
import { withRouter } from 'next/router'
3
import Link from 'next/link'
4
5
const  Test = ({router}) =>{
6
    return(
7
        <div>
8
            <p>{router.query.id}</p>
9
            <Link href={{pathname:'/'}}>
10
                <span>返回首页</span>
11
            </Link>
12
        </div>
13
    )
14
}
15
export default withRouter(Test)
16
17
//  router.query.id -> 123
     

 

7.路由-钩子事件

Next.js的路由钩子一共有六个

当路由发生变化时会触发钩子事件,这里用到Router的on方法来监听,钩子事件第二个参数为路由参数,这里来编 辑index.js页面。

Javascript          
xxxxxxxxxx
        1
//路由发生变化时
2
 Router.events.on('routeChangeStart',(...args)=>{
3
   console.log('路由开始变化',...args)
4
})
5
//路由结束变化时
6
 Router.events.on('routeChangeStart',(...args)=>{
7
   console.log('路由开始变化',...args)
8
})
9
//路由结束变化时触发
10
Router.events.on('routeChangeComplete',(...args)=>{
11
  console.log('路由结束变化',...args)
12
})
13
//在改变浏览器 history之前触发
14
Router.events.on('beforeHistoryChange,(...args)=>{
15
  console.log('浏览器 history改变之前',...args)
16
})
17
//跳转发生错误触发
18
Router.events.on('routeChangeError,(...args)=>{
19
  console.log('跳转发生错误',...args)
20
})
21
//hash模式路由改变刚开始
22
Router.events.on('hashChangeStart,(...args)=>{
23
  console.log('hash模式路由改变刚开始',...args)
24
})
25
//hash模式路由改变结束
26
Router.events.on('hashChangeComplete,(...args)=>{
27
  console.log('hash模式路由改变结束',...args)
28
})
     

 

8.getInitialProps 获取远程数据

通常需要从远程数据源获取数据.Next.js 自己有标准 API 来获取页面数据.我们通常使用异步函数 getInitialProps 来完成此操作 .这样,我们可以通过远程数据源获取数据到页面上,并将其作为 props 传递给我们的面.getInitialProps 在服务器和客户端上均可使用.

1).axios

Javascript          
xxxxxxxxxx
        1
npm install --save axios
2
3
4
...
5
//使用  打印出list
6
const Test = ({ router, list }) => {
7
  return (
8
    <>
9
      <div>{list}</div>
10
    </>
11
  );
12
};
13
Mock.mock("https://www.test.com", { list: "吃饭睡觉打豆豆" });
14
Test.getInitialProps = async () => {
15
  const promise = new Promise((resolve) => {
16
    axios("https://www.test.com").then((res) => {
17
      console.log("结果为:", res);
18
19
      resolve(res.data);
20
    });
21
  });
22
  return await promise;
23
};
24
export default withRouter(Test);
     

 

2).fetch

Javascript          
xxxxxxxxxx
      1
npm install --save isomorphic-unfetch
2
3
//使用
4
  Test.getInitialProps = async function (){
5
     const res = await fetch('https://www.test.com');
6
     const data = await res.json();
7
     console.log(data.map(entry => entry.show))
8




9

   }
     

 

9.组件样式

1).框架自带的一种语法style jsx ,来尝试一下让字体变成蓝色

直接写在return 中,可以在页面最外层添加一个<></>

Javascript          
xxxxxxxxxx
        1
<>
2
    <div className="container">
3
      <Test>按钮</Test>
4
    </div>
5
    <style jsx>
6
      {`
7
          .container { color:blue;}
8
      `}
9
    </style>
10
</>
     

2).动态改变组件样式

Javascript          
xxxxxxxxxx
        1
const Home = () => {
2
  const [color, setColor] = useState("blue");
3
  const changeColor = () => {
4
    setColor(color === "blue" ? "red" : "blue");
5
  };
6
  return (
7
    <>  
8
   <div>
9
      <Test>按钮</Test>
10
    </div>
11
      <button onClick={changeColor}>变色</button>
12
13
      <style jsx>
14
        {`
15
          div {
16
            color: ${color};
17
          }
18




19

        `}
20
      </style>
21
    </>
22
  );
23
};
24
export default Home;
25
     

打开控制台还会发现,加入了Style jsx代码后,Next.js会自动加入一个随机类名,这样就防止了CSS的全局污染。

3).引入less 和 css

当页面比较复杂的时候,我们以jsx方式来编写样式,难免的会降低我们的开发效率,所以这里尝试一下引入less

首先安装less 和 css

Javascript          
xxxxxxxxxx
      1
npm install --save @zeit/next-less less
2
npm install --save @zeit/next-css
     

 

然后在根目录下创建next.config.js配置文件,引入less和css

Javascript          
xxxxxxxxxx
        1
const withCss = require('@zeit/next-css')
2
3
const withLess = require('@zeit/next-less')
4
if(typeof require !== 'undefined'){
5
    require.extensions['.css']=file=>{}
6
}
7
8
if (typeof require !== "undefined") {
9
   require.extensions[".withLess"] = file => {};
10
 }
11
module.exports = withLess(withCss({}))
12
     

然后重新启动服务

4).引入antd

Javascript          
xxxxxxxxxx
      1
//首先安装antd依赖
2
npm install antd --save
3
4
//然后来安装和配置babel-plugin-import 插件
5
npm install babel-plugin-import --save-dev
     

 

安装完成后,在项目根目录建立.babelrc文件,然后写入如下配置文件。

Javascript          
xxxxxxxxxx
        1
{
2
    "presets":["next/babel"],  //Next.js的总配置文件,相当于继承了它本身的所有配置
3
    "plugins":[     //增加新的插件,这个插件就是让antd可以按需引入,包括CSS
4
        [
5
            "import",
6
            {
7
                "libraryName":"antd",
8
                "style":"css"
9
            }
10
        ]
11
    ]
12
}
     

这样配置好了以后,webpack就会按需引入antd,同样CSS也是按需打包的。

然后重启服务。

10.部署 Next.js 应用

先安装 now,一个静态资源托管服务器

Javascript          
xxxxxxxxxx
      1
npm i -g now
     

打包

Javascript          
xxxxxxxxxx
      1
yarn build
     

 

注: 结果发现报错了,其实是我们在加入Ant Design的样式时产生的,这个已经在Ant Design的Github上被提出了,但目前还没有被修改,你可以改完全局引入CSS解决问题。

解决办法

在page目录下,新建一个_app.js文件,然后写入下面的代码。

 

Javascript          
xxxxxxxxxx
      1
import App from 'next/app'
2
3
import 'antd/dist/antd.css'
4
5
export default App
6
     

 

再次运行

Javascript          
xxxxxxxxxx
      1
yarn build
2
yarn start
     

标签:渲染,Javascript,Next,xxxxxxxxxx,js,页面
来源: https://www.cnblogs.com/dorae91/p/16030394.html