前端小白如何快速编写react项目


顾名思义,本章主要是前端小白就【如何快速编写一个前端react项目】做的总结。前端大牛可移步~

背景

  组内有一个测试工具平台,直接用python的Django写的前端+后端。由于界面简陋+不专业+没有前后端分离,所以就想着对该平台做个前端重构。

框架选择的是公司大前端同款react框架。秉着快速重构完成为主,学习为辅的想法。

环境构建

手动构建

  1. 步骤:

    1. 安装node,npm

    2. 创建项目文件夹test_tools_web并进入

    3. 生成package.json文件(npm init -y)

    4. 安装react  (npm install --save react react-dom)

    5. 安装webpack (npm install --save-dev webpack webpack-cli)

    6. 创建webpack配置文件test_tools_web/config/webpack.common.config.js完成各种配置(参考链接)

    7. 创建项目目录以及页面,并启动

  2. 特点:

    1. 步骤复杂

    2. webpack配置非常的麻烦,需要提前学习
      webpack是前端资源模块化管理和打包工具,配置文件webpack.common.config.js配置起来非常的麻烦。webpack只认识js文件,不认识css,jsx等文件。所以如果需要打包这些文件,需要安装配置对应的loader插件进行预处理,还有热更新的插件,清除旧的打包文件啊,等等吧(webpack搭建参考https://juejin.im/post/5da5748851882555a8430641

自动构建

    1. 步骤:

      1. 安装node,npm 或 yarn
      2. 安装create_react_app (npm install -g create-react-app)
      3. 创建项目 create-react-app test_tools_web(yarn create react-app test_tools_web)
      4. 启动项目 cd test_tools_web 然后npm start 或yarn start
    2. 特点:

      create_react_app是一个React 应用开发工具,它会自动初始化一个脚手架并安装 React 项目的各种必要依赖,所以特点很明显

      1. 步骤简单

      2. 不需要重点花费时间学习配置webpack

      3. 节约时间

项目编写

因为webpack的坑比较多,本着‘快速重构完成为主,学习为辅’的需求,后续选择了create_react_app工具自动搭建环境,接下来举例第一个react页面编写~

  • 新建html文件test_tools_web/public/index.html
<!DOCTYPE html>
<html lang="en"> 
<head> 
<meta charset="UTF-8"> 
<meta name="viewport" content="width=device-width, initial-scale=1.0"> 
<title>测试工具</title> 
</head> 
<body> 
<div id="root"></div> 
</body> 
</html
index
  • 新建js文件test_tools_web/src/index.js

import React from 'react';
import ReactDom from 'react-dom';
import App from './views/app';
 
ReactDom.render((<App/>),document.getElementById('root'))
index.js
  • 新建react组件,APP

import React from 'react';
import '../style/app.less';
 
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      date: '',
    };
  }
  render() {
    return (
        <div className='app'>
            <div>
                <h1 className={'header'}>QA测试工具平台</h1>
            </div>
        </div>
    );
  }
}
 
export default App;
app.js
  • 启动命令yarn start

package.json是自动生成的,已经有了scripts配置,可以直接yarn start启动程序。当然如果想指定端口port为30000,可以改成下图start 命令代码

"scripts": {
  "start": "PORT=30000 react-app-rewired start",
package.json

antd介绍

antd 是基于 Ant Design 设计体系的 React UI 组件库,有丰富的UI基础组件可以参考,且很多企业在用。关于安装和简单的使用如下:

安装:yarn add antd

引入样式:import 'antd/dist/antd.css';

使用举例:

import { DatePicker } from 'antd';

ReactDOM.render(<DatePicker />, document.getElementById('div'));

具体的组件及使用文档,可去官网查看,简单易上手。非常适合我这样的前端小白(antd官网地址https://ant.design/docs/react/introduce-cn

编写主页

上面的举例已经清楚,APP.js就是主页。那如何去编写呢。

1. 需要构思UI设计

因为功能较少,我设计的是左侧菜单区+内容展示区

 

 2. 根据UI搭建布局

这里的布局直接参考的antd提供的布局

导入组件:import {Layout, Menu, Breadcrumb} from 'antd';
定义组件:const {Header, Content, Footer, Sider} = Layout;const {SubMenu} = Menu;
引用组件:
return (
            <Layout>
                <Header className='header'>
                    <img className='mai_logo' src={maimai_logo}></img>
                    <span style={{height: '100%',margin:'5px'}}>**测试工具平台</span>
                    <span style={{position: 'relative', left: '70%'}}>Welcome~</span>
                </Header>
                <Layout style={{minHeight: '100vh'}}>
                    <Sider collapsible collapsed={this.state.collapsed} onCollapse={this.onCollapse}
                           style={{padding_top: '0px'}}>
                        <Menu theme="blue" defaultSelectedKeys={['1']} defaultOpenKeys={['sub1','sub2','sub3']} mode="inline">
                            {/*注意方法是绑定bind或者箭头函数()=>*/}
                            <Menu.Item key="1" icon={<HomeOutlined/>} onClick={()=>this.changeContent('1','首页')}>
                                首页
                            </Menu.Item>
                            <SubMenu key="sub1" icon={<UserOutlined/>} title="用户信息查询">
                                <Menu.Item key="2" onClick={()=>this.changeContent('2','**查询')}>**查询</Menu.Item>
                                <Menu.Item key="3" onClick={()=>this.changeContent('3','万能转换器')}>万能转换器</Menu.Item>
                            </SubMenu>
                            <SubMenu key="sub2" icon={<ToolOutlined/>} title="自动化小工具">
                                <Menu.Item key="5" onClick={()=>this.changeContent('5','遍历参数测试')}>遍历参数测试</Menu.Item>
                                <Menu.Item key="6" onClick={()=>this.changeContent('6','node接口查询')}>node接口查询</Menu.Item>
                            </SubMenu>
                            <SubMenu key="sub3" icon={<FileOutlined/>} title="附加功能">
                                <Menu.Item key="7" onClick={()=>this.changeContent('7','URL编解码')}>URL编解码</Menu.Item>
                            </SubMenu>
                            <Menu.Item key="8" icon={<FileOutlined/>} onClick={()=>this.changeContent('8','其他')} title="其他">
                                其他
                            </Menu.Item>
                        </Menu>
                    </Sider>
                    <Layout className="site-layout">
                        <Content style={{margin: '0 16px'}}>
                            <Breadcrumb className='Breadcrumb_border'>
                                <Breadcrumb.Item className='Breadcrumb_Item'>{menuName}</Breadcrumb.Item>
                                {/*<Breadcrumb.Item className='Breadcrumb_Item'>万能转换器</Breadcrumb.Item>*/}
                            </Breadcrumb>
                            <div style={{padding: 24, minHeight: 360}}>
                                {this.getContent()}
                            </div>
                        </Content>
                        <Footer style={{textAlign: 'center'}}>Test_Tool Design ©2020 Created by MaiMai_QA</Footer>
                    </Layout>
                </Layout>
            </Layout>
App.js

3. 具体的交互思路

主要思路:点击左侧菜单,重置state值:contentIndex,再根据contentIndex值return不同的组件给<Content>

    changeContent =(key,name)=> {
        this.setState({contentIndex: key})
        this.setState({menuName:name})
    };
changeContent ()
    getContent() {
        let {contentIndex} = this.state;
        switch (contentIndex) {
            case '1':
                return (<Index/>);
            case '2':
                return(<Verifycode/>);
            case '3':
                return (<Translator/>);
            case '5':
                return(<ThroughParamsTest/>);
            case '6':
                return(<NodeApis/>);
            case '7':
                return(<UrlDecode/>);
            case '8':
                return(<Other/>)
        }
    };
getContent()

4. 基础组件的编写<Translator>举例

import React from 'react';
import '../App.less';
import {Input} from 'antd';
import {fetch_json} from './ComFuncs';
// import conf from '../conf.js';
import {config} from '../conf';
const {Search}= Input;


class Translator extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            SelectType:'uid',
            InputValue:'',
            Data:{}
        }
    };

    componentWillMount() {
    };

    componentDidMount() {
    };
    handleChange=(event) =>{
        this.setState({SelectType: event.target.value});
    }
    GetUserinfo = (value) => {
        if (value){
            this.setState({InputValue: value},()=>{
                let seltyp=this.state.SelectType;
                let inpval=this.state.InputValue;
                let params={'uid':0,'ouid':0,'mobile':'','emobile':'','tid':''};
                params[seltyp]=inpval;
                console.log('state----',params);
                fetch_json.call(this, config.online_url +'/qa_test/transition_api',params)
                    .then((res)=> {
                        if (res.rows[0]!={}){
                            return res.rows[0];
                        }
                        else {return {}}
                    }
                ).then((res)=>{this.setState({Data:res})})
            })
        }
    }

    render() {
        let {Data} = this.state;
        return (
            <div>
                <div>
                    <select name='seletions' style={{height:'32px',border_color:'lightgrey'}} onChange={this.handleChange}>
                        <option value={'uid'}>uid</option>
                        <option value={'ouid'}>ouid</option>
                        <option value={'mobile'}>mobile</option>
                        <option value={'emobile'}>emobile</option>
                        <option value={'tid'}>tid</option>
                    </select>
                    <Search style={{width:'200px'}} placeholder="输入查询值" onSearch={(value) => this.GetUserinfo(value)} enterButton />
                </div>
                {Data['uid']? (<div className='transtable'>
                    <span >查询结果:</span>
                    <table>
                        <tr>
                            <th>uid</th>
                            <th>realname</th>
                            <th>ouid</th>
                            <th>tid</th>
                            <th>mobile</th>
                            <th>emobile</th>
                        </tr>
                        <tr>
                            <td>{Data['uid']}</td>
                            <td>{Data['realname']}</td>
                            <td>{Data['ouid']}</td>
                            <td>{Data['tid']}</td>
                            <td>{Data['mobile']}</td>
                            <td>{Data['emobile']}</td>
                        </tr>
                    </table>
                </div>):null}

        </div>
    )
    }
}
export default Translator;
Translator

5. 导入与导出

导出:export default Translator;
导入:import Translator from './components/Translator';

6. 公共函数

import qs from 'querystring';

export function fetch_json(url='',req_dict={}) {
    return fetch(url, {
        method: 'POST',
        body: qs.stringify(req_dict),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        // mode:"no-cors"
    }).then((res)=>{return res.json()})
}
公共函数

项目目录:

总结

完事开头难!切忌【等学习熟练了再写】,这一等,往往就是一个月,半年,甚至n年。。。。。。所以我还是建议基础差不多就直接上手练~

重构后的页面,整体比之前高大上了很多,哈哈,还是挺有成就感的~

基础还是有很多不足,学习的路且长呢,一起加油~~~


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM