react服务端渲染Next的学习

记录一下Next的学习,
1:手动安装
2:自动安装
好,开始手动安装
//先安装依赖包

npm  init
cnpm  install  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文件夹,next会自动给我们设置路由,
//新建一个Index.js,代码如下

//react hooks
function Index(){
    return (
        
Hello,next
) } export default Index;

//启动,测试

npm  run  dev
react服务端渲染Next的学习_第1张图片
image.png
react服务端渲染Next的学习_第2张图片
image.png

启动成功啦

·······························································································
现在我们用工具脚手架来创建一个项目,工作中都是用这个方式哦
先来全局安装一下

cnpm  install  create-next-app -g
react服务端渲染Next的学习_第3张图片
image.png

创建项目
目前可以支持三种方式的创建,分别是用npx,yarn和create-next-app命令来进行安装
npx 是Node自带的npm模块,所以你只要安装了Node都是可以直接使用npx命令的。

但低版本的Node是不带这个命令的,所以你需要手都安装一下。

cnpm install -g npx

好,开始创建项目

npx create-next-app next-react
react服务端渲染Next的学习_第4张图片
image.png

启动

npm  run  dev
react服务端渲染Next的学习_第5张图片
image.png

看到上图就是成功啦
在pages新建一个index.js页面来测试

function user(){
    return(
        
    )
}

export default user;

image.png

浏览器输入http://localhost:3000/user,发现自动给我们添加了路由,好方便亚麻跌
react服务端渲染Next的学习_第6张图片
image.png

类似于一个js就是一个路由,那么如果是2级比如http://localhost:3000/concat/phone,怎么实现了?
其实也很简单,新建一个concat文件夹,里面新建phone.js就可以啦
//phone.js

export default ()=>{
    return 
好好学习React
}
react服务端渲染Next的学习_第7张图片
image.png
react服务端渲染Next的学习_第8张图片
image.png

那么如何新建一个组件了?

我们再components文件下下面,新建一个test.js,用来写我们的子组件

export  default ({children})=>{
    return 
}

ps:这里传值只能写children,用别的就不行哦

在首页中使用
index.js

import Test from '../components/test'
我是传递值

最后效果


image.png

接下来我们实现路由的跳转,具体有2个方式Link和Router.push,好上代码
新建一个home.js
//home.js


import Link from 'next/link';

import PageA from './pageA.js';
import PageB from './pageB.js';

function  home(){
    return(
        <>
            
我是Home页面
去A页面 去B页面 ) } export default home;

ps:官方推荐link里面用a标签包裹,否则会有警告

//pageA.js

import Link from 'next/link';
export  default ()=>{
    return (
        <>
            返回首页
            
我是AAA页面
) }

//pageB.js

import Link from 'next/link';
export  default ()=>{
    
    return (
        <>
            返回首页
            
我是BBB页面
) }

效果图


react服务端渲染Next的学习_第9张图片
image.png
react服务端渲染Next的学习_第10张图片
image.png
image.png

好,我们用单击事件来是线路有跳转

import Router  from 'next/router'
function  home(){
    return(
        <>
            
我是Home页面
去A页面 去B页面
) }
react服务端渲染Next的学习_第11张图片
image.png

image.png
image.png

用方法也是可以的哦

接下来讲解一下,路由传递参数和接受参数,next只支持query传递参数哦

去A页面
去B页面

这里传递2个参数name值,然后我们再pageA和pageB获取name值

import Link from 'next/link';
import {withRouter} from 'next/router';

 const pageA = ({router})=>{
    return (
        <>
            返回首页
            

我是参数:{router.query.name}

我是AAA页面
) } export default withRouter(pageA);

主要是使用了withRouter来接受路由参数哦

import Link from 'next/link';
import {withRouter} from 'next/router';

const pageB= ({router})=>{
    
    return (
        <>
            返回首页
            
我是接受到的参数:{router.query.name}
我是BBB页面
) } export default withRouter(pageB)
react服务端渲染Next的学习_第12张图片
image.png

image.png

函数传递也是可以的

//home.js
    function  gotoPage(){
        Router.push('/pageC?name=武汉')
    };
//pageC.js
import Link from 'next/link';
import {withRouter} from 'next/router';
const pageC= ({router})=>{
    return (
        <>
            返回首页
            
接受到的参数{router.query.name}
我是CCC页面
) } export default withRouter(pageC)
image.png

传递参数用面向对象试一下可以不?

    function  gotoPage(){
        Router.push({
            pathname:'/pageC',
            query:{
                name:"我爱武汉"
            }
        })
    };

效果是一样一样的


react服务端渲染Next的学习_第13张图片
image.png

接下来讲解下路由的生命周期钩子事件

//routeChangeStart 路由发送变化之前 
//routeChangeComplete   路由变化结束
//beforeHistoryChange    路由history开始变化
//routerChangeError   路由发送错误 
//hashChangeStart     hash路由开始改变之前
//  hashChangeComplete  hash路由开始改变完成     

具体代码
home.js

    Router.events.on('routeChangeStart',(...args)=>{
        console.log('1-routeChangeStart,路由开始变化了之前',...args)
    });
    Router.events.on('routeChangeComplete',(...args)=>{
        console.log('2-routeChangeComplete,路由开始变化完成结束',...args)
    });
    Router.events.on('beforeHistoryChange',(...args)=>{
        console.log('3-beforeHistoryChange,路由history开始变化',...args)
    });
    Router.events.on('routerChangeError',(...args)=>{
        console.log('4-routerChangeError,路由发送错误',...args)
    });
    //hash模式
    Router.events.on('hashChangeStart',(...args)=>{
        console.log('5-hashChangeStart,hash路由开始改变之前',...args)
    });
    Router.events.on('hashChangeComplete',(...args)=>{
        console.log('6-hashChangeComplete,hash路由开始改变完成',...args)
    });

效果图


react服务端渲染Next的学习_第14张图片
image.png

hash模式下

Hash模式
react服务端渲染Next的学习_第15张图片
image.png

接下来讲解远程获取数据,官方规定必须放在getInitialProps里面才可以

>cnpm  install axios --save
pageA.getInitialProps= async ()=>{
    //let api = "http://localhost:3333/api/list";
    let api = "/api/list";
    const  result  =  new  Promise((resolve)=>{
            axios(api).then(res=>{
                console.log(res.data.data);
                resolve(res.data.data)
            }).catch(err=>{
                console.log(err);
            });
    });
    return await result;
}

react服务端渲染Next的学习_第16张图片
image.png

接下来讲解一下,如何在next中写css

        <>
            返回首页
            
接受到的参数{router.query.name}
我是CCC页面
我是CCC页面
image.png

那么如何动态切换样式了,点一下变红点一下变蓝色

import  {useState} from 'react';
import Link from 'next/link';
import {withRouter} from 'next/router';
const pageC= ({router})=>{
    const [color,setColor]=useState('blue');
    const changeColor = ()=>{
        setColor(color=="blue"?"red":"blue")
    }
    return (
        <>
            返回首页
            
接受到的参数{router.query.name}
我是CCC页面
我是CCC页面
) } export default withRouter(pageC)

大功告成,接下来实现模块懒加载,优化打开速度

>cnpm  install moment --save
import  {useState} from 'react'
import {moment} from 'moment';

const  time= ()=>{
    const [nowTime,setTime]=useState(Date.now());
    const changeTime= ()=>{
        setTime(moment(Date.now()).format())
    }
    return(
        <>
        
{nowTime}
) } export default time;

使用懒加载之后

import  {useState} from 'react'

const  time= ()=>{
    const [nowTime,setTime]=useState(Date.now());
    const changeTime = async ()=>{
        let  moment =await import('moment');
        setTime( moment.default(Date.now()).format())
    }
    return(
        <>
        
{nowTime}
) } export default time;

ps:注意一定要加.default,否则报错,如何判断依据懒加载成功了?


react服务端渲染Next的学习_第17张图片
image.png

会发现从0.js又生成1.js,说明成功了~~~~~~

那么如何懒加载自定义组件了????

1:先再components里面新建one.js

export default ()=>{
    return 

我是自定义组件哦

}

2:使用

import dynamic from 'next/dynamic'
import One  from '../components/one';

写完代码后,可以看到自定义组件是懒加载的,只有在jsx里用到时,才会被加载进来,如果不使用就不会被加载。

当我们作的应用存在首页打开过慢和某个页面加载过慢时,就可以采用Lazy Loading的形式,用懒加载解决这些问题。

接下来讲解如何利用head实现网页的标题title

import Head  from 'next/head'

    我要成为React大神
     

image.png

那么如何全局引用了?
思路:万物皆组件,封装为一个组件,其他页面引用就可以啦
新建一个globalHeader.js作为全局组件
//globalHeader.js

import Head  from  'next/head'

export default ()=>{
    return(
        <>
            
                我是全局标题
            
        
    )
    
}

其他页面使用

import  GlobalHeader  from '../components/globalHeader';

效果图


react服务端渲染Next的学习_第18张图片
image.png
我们知道next不能直接导入css使用,这就很尴尬了,那么如何解决了?
react服务端渲染Next的学习_第19张图片
image.png

这里用了一个三方库@zeit/next-css来解决

cnpm install --save @zeit/next-css

根目录下新建一个next.config.js

const withCss = require('@zeit/next-css')

if(typeof require !== 'undefined'){
    require.extensions['.css']=file=>{}
}

module.exports = withCss({})

修改配置文件后,一定要重启服务


react服务端渲染Next的学习_第20张图片
image.png

大功告成,yeah~~~~~
接下来我们安装antd,这样界面就可以好看很多
1:安装antd

cnpm install antd --save

//注意:antd 默认支持基于 ES module 的 tree shaking,不使用以下插件也会有按需加载的效果。

按需加载

A使用 babel-plugin-import(推荐)。
B手动引入
这里我们用按需加载
2:配置按需加载
先安装按需加载的模块

>cnpm  install babel-plugin-import --save

根目录下面新建.babelrc 文件

{
  "presets":["next/babel"], //Next.js的总配置文件,相当于继承了它本身的所有配置  
  "plugins": [//增加新的插件,这个插件就是让antd可以按需引入,包括CSS
    ["import", {
      "libraryName": "antd",
      "style": "css" // `style: true` 会加载 less 文件
    }]
  ]
}

ps:presets是保留以前的配置,注意官网的libraryDirectory这个千万不要加,有个坑,加了编译报错无法访问
使用

import {Button} from 'antd';

react服务端渲染Next的学习_第21张图片
image.png

最后打包上线

npm  run  build

但是当你使用了Ant Desgin后,在打包的时候会遇到一些坑。我们引入了就会有如下问题
报错如下


react服务端渲染Next的学习_第22张图片
image.png

那么如何解决了?

1:修改.babelrc文件,去掉"style": "css"这一行

{
  "presets":["next/babel"], 
  "plugins": [
    ["import", {
      "libraryName": "antd"
    }]
  ]
}

2:在pages文件下下面新建一个_app.js,内容如下

import App  from  'next/app';

import 'antd/dist/antd.css';

export default App;

3:重新打包测试

npm run  build  

看到如下界面就成功啦


react服务端渲染Next的学习_第23张图片
image.png

4:启动测试

  "scripts": {
    "dev": "node server.js",
    "build": "next build",
    "start": "next start -p 80"
  },

启动

npm  run  start
react服务端渲染Next的学习_第24张图片
image.png

没有问题,大功告成~~~~~~~~~

你可能感兴趣的:(react服务端渲染Next的学习)