顧名思義,本章主要是前端小白就【如何快速編寫一個前端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年。。。。。。所以我還是建議基礎差不多就直接上手練~
重構后的頁面,整體比之前高大上了很多,哈哈,還是挺有成就感的~
基礎還是有很多不足,學習的路且長呢,一起加油~~~
