美文网首页
Next.js新手教程

Next.js新手教程

作者: fanzhh | 来源:发表于2019-12-08 11:02 被阅读0次

    Next.js 是一个轻量级的 React 服务端渲染应用框架。本教程演示使用Next.js制作一个显示比特币汇率的网站。详细的Next.js信息请访问https://nextjs.org/

    安装

    本文假设你使用的是windows操作系统,已经安装npm。npm的安装方法,请自行bing搜索。

    我使用的是visual studio code环境。命令行在该环境的terminal下输入、运行。当然你也可以使用其它环境如windows自带的powershell,使用写字板编辑代码。

    新建一个名为BitzPrice目录,并进入该目录。

    C:\Users\HP\projects>mkdir bitzprice
    C:\Users\HP\projects>cd bitzprice
    

    查看npm版本,确认你已经安装:

    PS C:\Users\HP\projects\bitzprices> npm --version
    6.12.1
    

    初始化:

    PS C:\Users\HP\projects\bitzprices> npm init -y
    Wrote to C:\Users\HP\projects\bitzprices\package.json:
    
    {
      "name": "bitzprices",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
    

    安装next、react和react-dom。某国访问境外网站非常慢,建议使用国内镜像加速,当然也可以不用。

    PS C:\Users\HP\projects\bitzprices> npm config set registry https://registry.npm.taobao.org
    PS C:\Users\HP\projects\bitzprices> npm install next react react-dom
    npm WARN deprecated core-js@2.6.10: core-js@<3.0 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual
    version of core-js@3.
    npm WARN deprecated fsevents@1.2.9: One of your dependencies needs to upgrade to fsevents
    v2: 1) Proper nodejs v10+ support 2) No more fetching binaries from AWS, smaller package size
    ...
    + react-dom@16.12.0
    + react@16.12.0
    + next@9.1.4
    added 760 packages from 356 contributors in 70.692s
    

    修改package.json

    现在目录下应该有package.json文件了。修改这个文件,将scripts部分修改为:

    "scripts": {
        "dev": "next",
        "build": "next build",
        "start": "next start"
      },
    

    建立index页面

    新建pages目录放置页面,在pages目录中新建Index.js文件,输入以下内容:

    export default () => (<div>Hello Next.js</div>)
    

    运行服务器

    terminal输入:

    C:\Users\Administrator\projects\bitzprice> npm run dev
    > bitzprices@1.0.0 dev C:\Users\HP\projects\bitzprices
    > next
    
    [ wait ]  starting the development server ...
    [ info ]  waiting on http://localhost:3000 ...
    [ ready ] compiled successfully - ready on http://localhost:3000
    

    现在浏览器访问http://localhost:3000,应该可以看到以下画面:

    index.js

    新建about页面

    pages中新建文件About.js,输入以下内容:

    export default () => (<div>About BitzPrices</div>)
    

    在浏览器输入http://localhost:3000/about,会看到以下内容:

    about.js

    让代码更React化

    Index.js修改成下面的样子:

    const Index = () => (
        <div>
            <h1>Hello BitzPrices</h1>
        </div>
    );
    
    export default Index;
    

    现在访问页面,应该是这样:

    index

    About.js也做类似修改:

    const About = () => (
        <div>
            <h1>About BitzPrices</h1>
            <p>查看比特币汇率的应用。</p>
        </div>
    );
    
    export default About;
    

    About页面:


    about

    添加导航

    我们使用nextLink作为导航。修改Index.js,内容如下:

    import Link from 'next/link';
    
    const Index = () => (
        <div>
            <ul>
                <li><Link href="/"><a>主页</a></Link></li>
                <li><Link href="/about"><a>关于</a></Link></li>
            </ul>
            <h1>Hello BitzPrices</h1>
        </div>
    );
    
    export default Index;
    

    修改About.js内容如下:

    import Link from 'next/link';
    
    const About = () => (
        <div>
            <ul>
                <li><Link href="/"><a>主页</a></Link></li>
                <li><Link href="/about"><a>关于</a></Link></li>
            </ul>
            <h1>关于BitzPrices</h1>
            <p>查看比特币汇率的应用。</p>
        </div>
    );
    
    export default About;
    

    刷新浏览器页面,应该能够使用导航了。

    about

    将导航栏放入部件中

    如果要创建多个页面,每个页面中都输入相同的代码显然太麻烦。我们可以将导航栏放入单独的部件,使用导航的页面只需要引入这个部件。

    bitzprices目录下新建components目录,在这个目录中新建Navbar.js文件,内容如下:

    import Link from 'next/link';
    
    const Navbar = () => (
        <ul>
            <li><Link href="/"><a>主页</a></Link></li>
            <li><Link href="/about"><a>关于</a></Link></li>
        </ul>
    );
    
    export default Navbar;
    

    Index.js现在只需要引入Navbar部件并使用它:

    import Navbar from '../components/Navbar';
    
    const Index = () => (
        <div>
            <Navbar />
            <h1>欢迎访问 BitzPrices</h1>
        </div>
    );
    
    export default Index;
    

    About.js也做相同修改。

    使用样式表

    我们在Navbar.js中展示样式表的使用,在文件中添加样式表,代码如下:

    import Link from 'next/link';
    
    const Navbar = () => (
        <div>
            <ul>
                <li><Link href="/"><a>主页</a></Link></li>
                <li><Link href="/about"><a>关于</a></Link></li>
            </ul>
    
            <style jsx>{`
                ul {
                    background: #333;
                    color: #fff;
                    list-style: none;
                    display: flex;
                }
    
                ul li {
                    font-size: 18px;
                    margin: 20px 20px 20px;
                }
    
                ul li a{
                    color: #fff;
                    text-decoration: none;
                }
            `}</style>
        </div>
    );
    
    export default Navbar;
    

    现在的页面如下:

    index

    这个样式表只对Navbar这个部件有效,不影响其它地方的<ul>

    使用布局

    components目录下新建Layout.js文件,内容如下:

    import Navbar from './Navbar';
    
    const Layout = (props) => (
        <div>
            <Navbar />
            {props.children}
        </div>
    );
    
    export default Layout;
    

    我们对Index.js做如下修改:

    import Layout from '../components/Layout';
    
    const Index = () => (
        <Layout>
            <div>
                <h1>欢迎访问 BitzPrices</h1>
            </div>
        </Layout>
    );
    
    export default Index;
    

    About.js的修改也一样:

    import Layout from '../components/Layout';
    
    const About = () => (
        <Layout>
            <div>
                <h1>关于BitzPrices</h1>
                <p>查看比特币汇率的应用。</p>
            </div>
        </Layout>
    );
    
    export default About;
    

    页面不会有任何变化,但我们现在已经使用布局了。

    添加页面标题及样式表引用

    修改Layout.js,引入Head,在Head中添加页面标题和样式表的引用(我们使用bootswatchcerulean样式)。Layout.js的内容:

    import Head from 'next/head';
    import Navbar from './Navbar';
    
    const Layout = (props) => (
        <div>
            <Head>
                <title>BitzPrices</title>
                <link rel="stylesheet"
                href="https://bootswatch.com/4/cerulean/bootstrap.min.css" />
            </Head>
            <Navbar />
            {props.children}
        </div>
    );
    
    export default Layout;
    

    刷新页面,


    index

    我们看到页面正文部分样式改变了,导航部分没有变。这是因为我们在Navbar.js中使用了样式表。为了应用cerulean样式,我们用ceruleanNavbar的源码代替Navbar.js的内容,注意要将所有的class=替换为className=,导航菜单内容及链接地址也做修改:

    const Navbar = () => (
        <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
            <a className="navbar-brand" href="/">BitzPrices</a>
            <button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor02" aria-controls="navbarColor02" aria-expanded="false" aria-label="Toggle navigation">
                <span className="navbar-toggler-icon"></span>
            </button>
    
            <div className="collapse navbar-collapse" id="navbarColor02">
                <ul className="navbar-nav mr-auto">
                    <li className="nav-item active">
                        <a className="nav-link" href="/">主页<span className="sr-only">(current)</span></a>
                    </li>
                    <li className="nav-item">
                        <a className="nav-link" href="/about">关于</a>
                    </li>
                </ul>
                <form className="form-inline my-2 my-lg-0">
                    <input className="form-control mr-sm-2" type="text" placeholder="Search"/>
                    <button className="btn btn-secondary my-2 my-sm-0" type="submit">Search</button>`
                </form>
            </div>
        </nav>
    );
    
    export default Navbar;
    

    将页面内容放入容器

    修改Layout.js,将{props.children}放入div中:

            <div className="container">
                {props.children}
            </div>
    

    通过API获取数据

    我们要获取的数据来自https://www.coindesk.com/,地址为https://api.coindesk.com/v1/bpi/currentprice.json,通过这个地址获取的json数据为:

    {
    "time":{
    "updated":"Dec 8, 2019 02:06:00 UTC",
    "updatedISO":"2019-12-08T02:06:00+00:00",
    "updateduk":"Dec 8, 2019 at 02:06 GMT"
    },
    "disclaimer":"This data was produced from the CoinDesk Bitcoin Price Index (USD). Non-USD currency data converted using hourly conversion rate from openexchangerates.org",
    "chartName":"Bitcoin",
    "bpi":{
    "USD":{"code":"USD","symbol":"&#36;","rate":"7,454.3000","description":"United States Dollar","rate_float":7454.3},
    "GBP":{"code":"GBP","symbol":"&pound;","rate":"5,674.7126","description":"British Pound Sterling","rate_float":5674.7126},
    "EUR":{"code":"EUR","symbol":"&euro;","rate":"6,740.6328","description":"Euro","rate_float":6740.6328}
    }
    }
    

    获取数据,我们需要用到isomorphic-unfetch。安装:

    PS C:\Users\HP\projects\bitzprices> npm install isomorphic-unfetch
    

    修改Index.js如下:

    import Fetch from 'isomorphic-unfetch';
    import Layout from '../components/Layout';
    
    const Index = (props) => (
        <Layout>
            <div>
                <h1>欢迎访问 BitzPrices</h1>
                {props.bpi.time.updated}
            </div>
        </Layout>
    );
    
    Index.getInitialProps = async function() {
        const res = await Fetch(
            'https://api.coindesk.com/v1/bpi/currentprice.json'
        );
        const data = await res.json();
        return {
            bpi: data
        }
    } 
    
    export default Index;
    

    刷新页面:


    index

    将Prices放入单独的部件

    components目录下,新建Prices.js文件,内容如下:

    class Prices extends React.Component {
        state = {
            currency: 'USD'
        }
    
        render() {
            return (<div>
                Prices
            </div>);
        }
    }
    
    export default Prices;
    

    修改Index.js内容,

    ...
    const Index = (props) => (
        <Layout>
            <div>
                <h1>欢迎访问 BitzPrices</h1>
                <Prices bpi={props.bpi} />
            </div>
        </Layout>
    );
    ...
    

    现在主页应该是这样:


    index

    显示汇率

    修改Index.js内容:

    import Fetch from 'isomorphic-unfetch';
    import Layout from '../components/Layout';
    
    import Prices from '../components/Prices';
    
    const Index = (props) => (
        <Layout>
            <div>
                <h1>欢迎访问 BitzPrices</h1>
                <p>当前的比特币汇率:</p>
                <Prices bpi={props.bpi} />
            </div>
        </Layout>
    );
    
    Index.getInitialProps = async function() {
        const res = await Fetch(
            'https://api.coindesk.com/v1/bpi/currentprice.json'
        );
        const data = await res.json();
        return {
            bpi: data
        }
    } 
    
    export default Index;
    

    修改Prices.js内容:

    class Prices extends React.Component {
        state = {
            currency: 'USD'
        }
    
        render() {
            return (<div>
                <ul className="list-group">
                    <li className="list-group-item">
                        Bitcoin rate for {this.props.bpi.bpi.USD.description}:<span className="badge badge-primary">{this.props.bpi.bpi.USD.code}</span><strong>{this.props.bpi.bpi.USD.rate}</strong>
                    </li>
                </ul>
            </div>);
        }
    }
    
    export default Prices;
    

    刷新页面:


    index

    获取其它币种汇率

    修改Prices.js,增加获取其它币种的数据:

    class Prices extends React.Component {
        state = {
            currency: 'EUR'
        }
    
        render() {
            let list = '';
    
            if (this.state.currency === 'USD') {
                list = <li className="list-group-item"> Bitcoin rate for {this.props.bpi.bpi.USD.description}:<span className="badge badge-primary">{this.props.bpi.bpi.USD.code}</span><strong>{this.props.bpi.bpi.USD.rate}</strong></li>
            } else if (this.state.currency === 'GBP') {
                list = <li className="list-group-item"> Bitcoin rate for {this.props.bpi.bpi.GBP.description}:<span className="badge badge-primary">{this.props.bpi.bpi.GBP.code}</span><strong>{this.props.bpi.bpi.GBP.rate}</strong></li>
            } else if (this.state.currency === 'EUR') {
                list = <li className="list-group-item"> Bitcoin rate for {this.props.bpi.bpi.EUR.description}:<span className="badge badge-primary">{this.props.bpi.bpi.EUR.code}</span><strong>{this.props.bpi.bpi.EUR.rate}</strong></li>
            }
    
            return (<div>
                <ul className="list-group">
                    {list}
                </ul>
            </div>);
        }
    }
    
    export default Prices;
    

    现在,因为currency的值为EUR,刷新页面,应该能够看到如下画面:

    index

    动态选择要查询的币种

    修改Prices.js

    class Prices extends React.Component {
        state = {
            currency: 'USD'
        }
    
        render() {
            let list = '';
    
            if (this.state.currency === 'USD') {
                list = <li className="list-group-item"> Bitcoin rate for {this.props.bpi.bpi.USD.description}:<span className="badge badge-primary">{this.props.bpi.bpi.USD.code}</span><strong>{this.props.bpi.bpi.USD.rate}</strong></li>
            } else if (this.state.currency === 'GBP') {
                list = <li className="list-group-item"> Bitcoin rate for {this.props.bpi.bpi.GBP.description}:<span className="badge badge-primary">{this.props.bpi.bpi.GBP.code}</span><strong>{this.props.bpi.bpi.GBP.rate}</strong></li>
            } else if (this.state.currency === 'EUR') {
                list = <li className="list-group-item"> Bitcoin rate for {this.props.bpi.bpi.EUR.description}:<span className="badge badge-primary">{this.props.bpi.bpi.EUR.code}</span><strong>{this.props.bpi.bpi.EUR.rate}</strong></li>
            }
    
            return (<div>
                <select onChange={e => this.setState({currency: e.target.value})} className="form-control">
                    <option value="USD">USD</option>
                    <option value="GBP">GBP</option>
                    <option value="EUR">EUR</option>
                </select>
                <ul className="list-group">
                    {list}
                </ul>
                <br/>
            </div>);
        }
    }
    
    export default Prices;
    

    现在可以选择要查询的币种了:

    index

    本文章内容参考了Traversy Media在Youtube上的视频

    相关文章

      网友评论

          本文标题:Next.js新手教程

          本文链接:https://www.haomeiwen.com/subject/juspgctx.html