从零开始,搭建React项目,篇一(搭建react项目、在react项目中使用Sass、react-router-dom、antd)

一、创建项目

注意: 创建项目的时候,记得暴露配置文件 ( npm run eject 或者 yarn run eject

因为暴露配置的文件的操作不可逆,之前没有提及git的话,可能会报错,还需重新git add . ; git commit -m "初始化(备注)"

yarn global add create-react-app  /* 本地全局安装 react 脚手架 */

create-react-app my-react-demo   /* 创建一个名为 my-react-demo 的React项目 */

cd my-react-demo /* 进入项目根目录 */

yarn run eject  /*  放出配置信息; //新版本的脚手架把配置文件等都以依赖的形式放到 node_modules 中了, eject 一下,把配置信息释放出来 */

yarn start   /* 运行项目 */ 

全局安装React脚手架,成功:
在这里插入图片描述
创建一个名为 my-react-demoReact项目成功:
在这里插入图片描述
③: 进入项目根目录,并运行 yarn run eject 成功:
在这里插入图片描述在这里插入图片描述
对比: 未执行 yarn run eject命令的项目和执行了 yarn run eject 的项目结构对比:(多了配置文件,访问效果相同
在这里插入图片描述在这里插入图片描述
在项目目录的scripts文件夹下的start.js中可以修改端口号 ( 默认端口是 3000
在这里插入图片描述
在这里插入图片描述

运行效果如下:
在这里插入图片描述
参考:https://www.cnblogs.com/pengfei-nie/p/10443310.html#a1

二、精简项目

1. 删除文件( 删除一般项目中用不到的文件,最简化项目 )

在这里插入图片描述在这里插入图片描述
删除上述文件后,项目目录结构如下:
public下的favicon.ico是网页图标;public下的index.htmlHTML模板;src下的index.js文件是项目的入口文件;src下的App.js是项目主模块)
在这里插入图片描述

2. 简化代码(删除这些文件和代码后,相应的文件引用已不存在,项目报错,需修改代码)

src 下的index.js 修改如下:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));

src下的APP.js修改如下:

import React from 'react';
function App() {
  return (
    <div className="App">
      <h1>App page</h1>
    </div>
  );
}
export default App;

public下的index.html修改如下:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

运行效果如下:
在这里插入图片描述

3. 使用Fragment去掉组件外层标签

react要求每个组件返回 JSX 时,的最外层必须是由一个标签包裹,且不能存在并列的标签。

① 例如,在src/App.js中,如果是这样就会报错:

 // 以下代码将会报错,最外层不能存在并列的标签。
import React from 'react';
function App() {
  return (
      <div className="App">
          <h1>This is React App1</h1>
      </div>
     <div className="App">
         <h1>This is React App2</h1>
    </div>
  );
}
export default App;

② 正解: 最外层必须是由一个标签包裹,所以这里,idapp_outside 这个div标签是必须的,但是,这样在渲染的时候,DOM 结构将更深一层

import React  from 'react';
function App() {
  return (
    <div id="app_outside">
          <div className="App">
              <h1>This is React App1</h1>
          </div>
          <div className="App">
             <h1>This is React App2</h1>
          </div>
    </div>
  );
}
export default App;

div作为最外层的时候,渲染出的DOM结构:
在这里插入图片描述

③ 有时,我们如果确实需要两个DOM 并列的DOM 结构,且并不想再添加一个父级标签,这个时候,我们就可以使用Fragment作为最外层。此时渲染的结构中:

import React, { Fragment } from 'react'
function App() {
  return (
        <Fragment>
          <div className="App">
              <h1>This is React App1</h1>
          </div>
          <div className="App">
             <h1>This is React App2</h1>
           </div>
        </Fragment>
  );
}
export default App;

Fragment 作为最外层的时候,渲染出的DOM结构如下:
在这里插入图片描述
博客参考https://juejin.im/post/5e36b72ee51d45307546b29c#heading-14

三、完善目录结构

1. 项目的目录结构,可按照个人开发习惯和项目实际来定,如:

  	  assets            静态资源文件夹,存放 字体、图片、css样式 等
      components        公共组件文件夹,放公共组件
      layouts           布局文件夹,  项目布局
      utils             公共函数文件夹  存放公共函数、一些插件的启动配置函数
      pages             具体的功能模块,  存放项目的实际页面
      services          接口文件夹  存放所有请求
      store             装redux的

如在src下新建了assets文件夹:
在这里插入图片描述

四、安装相应的插件,并使用

1. 安装Sass

(React 支持Sass/Less/Stylus,习惯用sasseject后,package.json以及webpack.config.js里有了sass相关代码,但要正确使用Sass/Scss,还需安装node-sass

1) 安装

yarn add node-sass

安装完成便可在项目中直接使用sass的语法 (记得 把 .css的后缀名改成 .scss )

2) 使用sass

如:在项目的src下新增了assets文件夹及其子文件夹:
在这里插入图片描述
global.scss ( 全局公用样式 )

body{
    background: lightyellow;
    h1{
        color:rgb(247, 6, 6)
    }
}

src下的index.js中引入了global.scss

import "./assets/style/global.scss" ; /*  + 引入全局公用样式global.scss文件 */
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'; /* APP 组件 是使用Fragment 作为最外层那个文件,未做任何改变 。*/
ReactDOM.render(<App />, document.getElementById('root'));

效果如图:
在这里插入图片描述

2. 安装路由插件:react-router-dom

1)安装:

 yarn add  react-router-dom 

2)使用使用react-router-dom

header / header.scss :

.header{
    background: #fff;
    .nav{
        display: inline-block;
        width: 100px;
        text-decoration: none;
        text-align: center;
        background: #dedede;    
        color: #333;
        padding: 12px;
    }
    .nav_active{
        background: tomato;
        color: #fff;
    }
}

header / index.js :

注意:

NavLink 是导航链接,activeClassName是元素处于活动状态时提供的类;此处的,exact是必须的,为true,表示path完全匹配时,才会应用活动的样式;

import React,{Component} from 'react';
import {NavLink} from 'react-router-dom'
import "./header.scss";

class Header extends Component{
    render(){
       
        return (
            <div className="header">
                <NavLink exact  to="/" activeClassName="nav_active"   className="nav">Home</NavLink>
                <NavLink to="/login"  className="nav"  activeClassName="nav_active"  >Login</NavLink>
            </div>
        )
    }
}
export default Header;

home / index.js :

import React, {Component,Fragment} from 'react';
import Header from '../../components/header'; /* 引入header文件夹下的index.js文件中定义的Header组件 */
class Home extends Component{
    render(){
        return (
            <Fragment>
                <Header></Header>
                <h2>Home page</h2>
                <p>This is home page.</p>
            </Fragment>
        )
    }
}

export default Home;

login / index.js :

import React,{Component, Fragment} from 'react';
import Header from '../../components/header'; /* 引入header文件夹下的index.js文件中定义的Header组件 */

class Login extends Component{
    render(){
        return (
            <Fragment>
                <Header></Header>
                <h2>Login page</h2>
                <p>This is login page.</p>
            </Fragment>
        )
    }
}

export default Login;

src / App.js

 import React, { Fragment } from 'react'
 import {HashRouter,Switch,Route,Redirect } from 'react-router-dom'
import Home from './pages/home';
import Login from './pages/login';
function App() {
  return (
        <Fragment>
          <HashRouter>
            <Switch>
            <Route exact path="/" component={Home}></Route>
            <Route path="/login" component={Login}></Route>
            <Route path="/home" component={Home}></Route>
            <Redirect to="/home"></Redirect>
            </Switch>
          </HashRouter>
        </Fragment>
  );
}
export default App;

注意:

1. App.js引入了HomeLogin两个页面级组件。然后使用react-router-dom分别设置了路径。

2. import的机制是默认寻找index.js,所以每个组件的主文件名设为index.js,在引用的时候就可以省略文件名

3. 注意 <Route>的属性:

path  表示路径。
component  表示绑定的组件。
exact  表示是否精确匹配,如果没有设置exact,那只要path中含有 ' / ',路由就会成功,就会匹配到Home页,那'/login'也会匹配到Home页
<Redirect>表示以上都没有匹配成功的,会默认跳转的路由。

src下的index.js :

import "./assets/style/global.scss" ; /*  + 引入全局公用样式global.scss文件 */
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'; 
ReactDOM.render(<App />, document.getElementById('root'));

效果如图:
在这里插入图片描述在这里插入图片描述
react-router-dom 更多信息 ,参考官网:https://reacttraining.com/react-router/web/guides/quick-start

五、React项目中 使用antd( Ant Design)

实现antd在react项目中的按需引入

1. 安装antd

yarn add antd

2. 引入并使用:

  • React中使用Ant Design 组件,Form表单的使用示例:
    篇一中的各文件和结构不做任何变化,修改login/index.js文件如下:
    login / index.js :
import React,{Component, Fragment} from 'react';
import Header from '../../components/header';

import 'antd/dist/antd.css'; /* 1. 引入antd的样式文件 */
import {Form,Input,Button} from 'antd'; /* 2. 引入所需的antd组件 */

import "./login.scss" /* 引入当前文件夹下的login.scss样式文件 */

const layout ={
    labelCol:{span:3},
    wrapperCol:{offset:1,span:10}
}

const onFinish=values=>{
    console.log(values) // 打印结果如:{userName: "na", pwd: "111111"}
}

const onFinishFailed=errorInfo=>{
    console.log('Failed:',errorInfo);
}

const rules={
    userName:[{required:true,message:'请输入用户名'}],
    pwd:[{required:true,message:'请输入密码'}]
}
class Login extends Component{
    render(){
        return (
            <Fragment>
                <Header></Header>
                <h2>Login page</h2>
                <p>This is login page.</p>
                <div className="login_outside">
            <Form 
                {...layout}
                name="basic"
                initialValues={{remember:true}}
                onFinish={onFinish}
                onFinishFailed={onFinishFailed}
            >
                <Form.Item label="用户名:" name="userName" rules={rules.userName}>
                    <Input />
                </Form.Item>
                <Form.Item label="密码:" name="pwd" rules={rules.pwd}>
                    <Input.Password/>
                </Form.Item>
                <Form.Item >
                    <Button className="login_btn" type="primary" danger htmlType="submit">登录</Button>
                </Form.Item>
            </Form>
          </div>

            </Fragment>
        )
    }
}
export default Login;

login/login.scss :

.login_outside{ width: 600px;  }  
.login_btn{width:200px;margin-left: 100px; }

src / index.js :

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "./assets/style/global.scss"
ReactDOM.render(<App />, document.getElementById('root'));

效果及项目目录结构如图:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
github项目地址: https://github.com/ddx2019/my-react-demo
( 项目中新加了swiper插件 )

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章