顾名思义,本章主要是前端小白就【如何快速编写一个前端react项目】做的总结。前端大牛可移步~
背景
组内有一个测试工具平台,直接用python的Django写的前端+后端。由于界面简陋+不专业+没有前后端分离,所以就想着对该平台做个前端重构。
框架选择的是公司大前端同款react框架。秉着快速重构完成为主,学习为辅的想法。
环境构建
手动构建
-
步骤:
-
安装node,npm
-
创建项目文件夹test_tools_web并进入
-
生成package.json文件(npm init -y)
-
安装react (
npm install --save react react-dom) -
安装webpack (npm install --save-dev webpack webpack-cli) -
创建webpack配置文件test_tools_web/config/
webpack.common.config.js完成各种配置(参考链接) -
创建项目目录以及页面,并启动
-
-
特点:
-
步骤复杂
-
webpack配置非常的麻烦,需要提前学习
webpack是前端资源模块化管理和打包工具,配置文件webpack.common.config.js配置起来非常的麻烦。webpack只认识js文件,不认识css,jsx等文件。所以如果需要打包这些文件,需要安装配置对应的loader插件进行预处理,还有热更新的插件,清除旧的打包文件啊,等等吧(webpack搭建参考https://juejin.im/post/5da5748851882555a8430641)
-
自动构建
-
步骤:
- 安装node,npm 或 yarn
- 安装create_react_app (npm install -g create-react-app)
- 创建项目 create-react-app test_tools_web(yarn create react-app test_tools_web)
- 启动项目 cd test_tools_web 然后npm start 或yarn start
-
特点:
create_react_app是一个React 应用开发工具,它会自动初始化一个脚手架并安装 React 项目的各种必要依赖,所以特点很明显
-
步骤简单
-
不需要重点花费时间学习配置webpack
-
节约时间
-
项目编写
因为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
-
新建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'))
-
新建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;
-
启动命令yarn start
package.json是自动生成的,已经有了scripts配置,可以直接yarn start启动程序。当然如果想指定端口port为30000,可以改成下图start 命令代码
"scripts": {
"start": "PORT=30000 react-app-rewired start",
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>
3. 具体的交互思路
主要思路:点击左侧菜单,重置state值:contentIndex,再根据contentIndex值return不同的组件给<Content>
changeContent =(key,name)=> { this.setState({contentIndex: key}) this.setState({menuName:name}) };
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/>) } };
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;
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年。。。。。。所以我还是建议基础差不多就直接上手练~
重构后的页面,整体比之前高大上了很多,哈哈,还是挺有成就感的~
基础还是有很多不足,学习的路且长呢,一起加油~~~
