5

通过React16.8构建新闻网站第二章:项目构建和项目布局的规划

 3 years ago
source link: https://zhuanlan.zhihu.com/p/248172591
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

通过React16.8构建新闻网站第二章:项目构建和项目布局的规划

北京奇观技术有限责任公司 软件开发工程师

专栏地址:

  1. 项目的初始化
  2. 项目路由的搭建
  3. 项目的布局的构建

1 使用create-react-app脚手架

$ npx create-react-app news

2 把webpack配置文件暴露出来 方便后期修改

$ npm run eject  然后输入y
$ npm start

备注:我这边运行出现了Error: [BABEL] D:\xx\xx\news\node_modules\react-dev- utils\webpackHotDevClient.js: Cannot find module '@babel/helper-create-regexp-features-plugin'这个报错,直接运行cnpm install @babel/helper-create-regexp-features-plugin 在重新npm start。

(这里提前npm run eject 也是因为这个 后期在运行这个时经常会出现某个包错误导致项目无法运行)

页面呈现:

3 git版本控制

 $git init  

我这里使用github客户端导入初始化的项目

暂时在本地进行版本控制

4 为项目引入antd

 $ cnpm install antd

删除app.css内的全部代码 引入@import '~antd/dist/antd.css';

5 为项目搭建路由

使用history、react-router-dom、react-router-config三个包

cnpm install history react-router-dom react-router-config

(使用react-router-config这个包是为了使用renderRoutes(routes)这个api它可以帮助我们解析对象形式routes,很方便的完成路由的抽离)

开始搭建路由

1 在src下建立一个routes.js

import React from 'react';
//因为暂时没有任何页面 先简单定义一个主页
const Index = ()=>{
    return(
        <div>
            我是主页
        </div>
    )
}
//配置路由  通过一个数组
var Routes = [   
    {
        path: '/',
        component: Index
    },
    {
        path: '/index',
        component: Index
    }
]
//把路由配置暴露出去
export default Routes

2 修改app.js

import React from 'react';
import './App.css';
//配置hashRouter 使用独立的router文件
import { createHashHistory } from 'history';
import { HashRouter as Router } from 'react-router-dom';
import { renderRoutes } from 'react-router-config';
//引入配置的routes
import Routes from './routes';

//创建路由history
const history = createHashHistory();

function App() {
  return (
    <div className="App">
      <Router history={history}>
       {/* 通过renderRoutes解析routes */}
        {renderRoutes(Routes)}
      </Router>
    </div>
  );
}

export default App;

页面效果:

6 建立布局

使用scss

cnpm install node-sass

布局的目录结构

我们的BaseLayout组件需要 NewsFooter组件和NewHeader组件 NewsHeader组件需要Nav组件

1 BaseLayout组件

通过renderRoutes 把 这个路由配置下的全部页面渲染到content中

import React, { useState, useEffect } from 'react';
import NewsHeader from './NewsHeader/index';
import NewsFooter from './NewsFooter/index';
//引入renderRoutes
import { renderRoutes } from 'react-router-config';
import { Layout } from 'antd';
import './index.scss';

const { Content } = Layout;

const BaseLayout = props => {
    return (
        <Layout className="layout">
            <NewsHeader />
            <Content style={{ padding: '0 50px' }}>
                <div className="site-layout-content">
                    {renderRoutes(props.route.children)}
                </div>
            </Content>
            <NewsFooter /> 
        </Layout>
    )
}
export default BaseLayout;

2 NewsFooter组件

import React, { useState, useEffect } from 'react';
import { Layout } from 'antd';

const { Footer } = Layout;

const NewsFooter = props=> {
    return(
        <Footer style={{ textAlign: 'center' }}>
            News Web ©2020 Created by ZYX
        </Footer>
    )
}
export default NewsFooter;

3 NewsHeader组件

import React, { useState, useEffect } from 'react';
import { Row ,Col } from 'antd';
//引入导航
import Nav from './Nav';
import './index.scss';


const NewsHeader = ()=> {

    //导航切换 current参数
    const [current,setCurrent] = useState('mail');

    //点击切换 修改current
    const handleClick = e => {
        setCurrent(e.key)
    };

    return(
        <div className='new-header'>
            <header>
                <Row>
                    <Col span={2}></Col>
                    <Col span={4}>
                        <a className='logo' href='/'>
                            <img src='https://1978246522-max.oss-cn-hangzhou.aliyuncs.com/logo.png' alt='logo'/>
                            <span>新闻</span>
                        </a>
                    </Col>
                    <Col span={18}>
                        <Nav 
                            current={current}
                            menuItemClick={handleClick}/>
                    </Col>
                </Row>
            </header>
        </div>
    )
}

export default NewsHeader;

//css代码
/*设置logo为弹性布局,设置弹性容器侧轴对齐方式为居中对齐*/
.new-header{
    .logo{
        display: flex;
        align-items: center;
        img{
            width:48px;
            height: 48px;
        }
        span{
            font-size: 24px;
            padding-left: 5px;
        }
    }
}

4 Nav组件

import React, { useState, useEffect } from 'react';
import {Menu} from 'antd';
import {Link} from 'react-router-dom';
import {AppstoreOutlined } from '@ant-design/icons';
import './index.scss';

//建立导航
const Nav = props =>{
    return(
         <Menu mode="horizontal" selectedKeys={[props.current] }
                style={{background: '#f0f2f5'}}
                onClick={props.menuItemClick}
                >
            <Menu.Item key="index" icon={<AppstoreOutlined />}>
                <Link to='/index'>
                    主页
                </Link>
            </Menu.Item>

            <Menu.Item key="artcle" icon={<AppstoreOutlined />}>
                <Link to='/artcle'>
                   文章
                </Link>
            </Menu.Item>

            <Menu.Item key="posting" icon={<AppstoreOutlined />}>
                <Link to='/posting'>
                    帖子
                </Link>
            </Menu.Item>

            <Menu.Item key="login" icon={<AppstoreOutlined />}>
                <Link to='/login'>
                   登录
                </Link>
            </Menu.Item>
        </Menu>

    );
};
export default Nav;

5修改routes.js

+ import BaseLayout from './container/BaseLayout/index';
修改
var Routes = [   
    {   
        path: '/',
        component: BaseLayout,
        children: [
            {
                path: '/',
                exact: true,
                component: Index
            },
            {
                path: '/index',
                exact: true,
                component: Index
            },
        ]
     },
]

渲染效果:




About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK