前端小白如何快速編寫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