美文网首页
练习React全栈项目:招聘SPA(一)

练习React全栈项目:招聘SPA(一)

作者: 是蜜桃啊 | 来源:发表于2020-06-06 00:34 被阅读0次

第一部分 :准备

1). 项目描述: 整体业务功能/功能模块/主体的技术/开发模式
2). 技术选型: 数据展现/用户交互/组件化, 后端, 前后台交互, 模块化, 项目构建/工程化, 其它
3). API接口: 接口的4个组成部分, 接口文档, 对/调/测接口

1.1 项目描述

1) 此项目为一个前后台分离的招聘的SPA, 包括前端应用和后端应用 
2) 包括用户注册/登陆, 大神/老板列表, 实时聊天等模块 
3) 前端: 使用 React 全家桶+ES6+Webpack 等技术 
4) 后端: 使用 Node+express+mongodb+socketIO 等技术 
5) 采用模块化、组件化、工程化的模式开发

1.2 技术选型

在这里插入图片描述

1.3 前端路由

1)注册
    - /register
    - register.jsx
2)登录
    - /login
    - login.jsx
3)主界面 main.jsx
    ① 老板主界面
        - /laoban
        - laoban.jsx
    ② 大神主界面
        - /dashen
        - dashen.jsx
    ③ 消息主界面
        - /message
        - message.jsx
    ④ 个人中心界面
        - /personal
        - personal.jsx
    ⑤ 老板信息完善界面
        - /laobaninfo
        - laoban-info.jsx
    ⑥ 大神信息完善界面
        - /dashenindo
        - dasheninfo.jsx
    ⑦ 聊天界面
        - /chat/:userid
        - chat.jsx

1.4 API接口

1.5 能从此项目中学到什么

1.5.1 流程及开发方法

1) 熟悉一个项目的开发流程 
2) 学会模块化、组件化、工程化的开发模式 
3) 掌握使用 create-react-app 脚手架初始化 react 项目开发 
4) 学会使用 node+express+mongoose+mongodb 搭建后台开发

1.5.2 React插件或第三方库

1) 学会使用 react-router-dom 开发单页应用 
2) 学会使用 axios 与后端进行数据交互 
3) 学会使用 redux+react-redux+redux-thunk 管理应用组件状态 
4) 学会使用 antd-mobile 组件库构建界面 
5) 学会使用 mongoose 操作 mongodb 数据
6) 学会使用 express 搭建后台路由 
7) 学会使用 socket.io 实现实时通信 
8) 学会使用 blueimp-md5 对密码进行 MD5 加密处理 
9) 学会使用 js-cookies 操作浏览器端 cookie 数据

1.6 git常用命令

* git config --global user.name "username" //配置用户名 
* git config --global user.password "xx@gmail.com" //配置邮箱 
* git init //初始化生成一个本地仓库 
* git clone url //将远程仓库克隆下载到本地 
* git add * //添加到暂存区 
* git commit –m “message” //提交到本地仓库 
* git remote add origin url //关联到远程仓库 
* git push origin master //push 到远程 
* git pull origin master //从远程 pull 更新

1.7. npm 常用命令

npm init //初始化当前应用包, 生成 package.json
npm install //根据 package.json 下载所有依赖包 
npm install packageName --save //下载某个运行时依赖包 
npm install packageName --save-dev //下载某个开发编译期依赖包
npm install packageName -g //全局下载某个依赖包 
npm install package@version //下载指定版本的某个依赖包 
npm info packageName //查看某个包有远程仓库中的相关信息 
npm rm packageName --save //移除已下载的运行依赖包 
npm rm packageName –save-dev //移除已下载的开发依赖包 
npm list //查看安装的所有的包
npm help //查看命令的详细帮助
npm install -g cnpm --registry=https://registry.npm.taobao.org //安装淘宝镜像 
npm config set registry="https://registry.npm.taobao.org" //将淘宝镜像设置为 npm 的默认仓库 
npm run xxx //执行 package.json 的 scripts 中配置的命令 
npm root -g //查看全局下载目录

第二部分 应用开发

2.1 开启项目开发

2.1.1 搭建项目

1) create-react-app 是 react 官方提供的用于搭建基于 react+webpack+es6 项目的脚手架 
2) 操作: npm install -g create-react-app : 全局下载工具 
        create-react-app gzhipin-client :下载模板项目 
        cd gzhipin 
        npm start 
        访问: localhost:3000

2.1.2 编码测试与打包发布项目

1) 编码测试 
    npm start 
    访问: http://localhost:3000 
    编码, 自动编译打包刷新(live-reload), 查看效果 
2) 打包发布 
    npm run build
    npm install -g serve
    serve build 
    访问: http://localhost:5000

2.2 功能需求分析

对功能模块进行分析说明

2.3 项目(前端)源码目录设计

  • src //客户端代码文件夹
    • api //ajax请求相关模块文件夹
    • assets //公共资源文件夹
    • components //UI组件模块文件夹
    • containers //容器组件模块文件夹
    • redux //redux相关模块文件夹
    • utils //工具模块文件夹
      • index.js //入口JS

2.4 引入 antd-mobile

2.4.1 下载组件库包

npm install antd-mobile --save

2.4.2 页面处理:index.html

移动端点击延迟0.3秒问题 (用fastclick库)
<script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script> 
<script> 
      if ('addEventListener' in document) 
        {
          document.addEventListener('DOMContentLoaded', function() 
            { 
              FastClick.attach(document.body); }, false); } 
              if(!window.Promise) { 
                document.writeln(
                  '<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js" '+'>'+'<'+'/'+'script>'
                    ); 
                  } 
</script>

2.4.3 实现组件的按需打包

  1. 下载依赖模块
npm install --save-dev babel-plugin-import react-app-rewired 
  1. 定义加载配置的 js 模块:config-overrides.js
const {injectBabelPlugin} = require('react-app-rewired'); 
module.exports = function override(config, env) {
    config = injectBabelPlugin(['import', {libraryName: 'antd-mobile', style: 'css'}], config); 
    return config; 
}

修改配置:package.json

"scripts": {   
    "start": "react-app-rewired start", 
    "build": "react-app-rewired build",
    "test": "react-app-rewired test --env=jsdom", 
    "eject": "react-scripts eject" 
}

2.4.4 在应用中使用 antd组件

import React from 'react' 
import ReactDOM from 'react-dom' 
import {Button} from 'antd-mobile'
ReactDOM.render( <Button type='primary'>Test</Button>, document.getElementById('root') )

2.4.5 运行测试出现问题

①此时运行项目后会出现问题,运行npm start或者yarn start 报错injectBabelPlugin is not a function

原因是react-scripts 升级到 2.1.2 以后破坏了 react-app-rewired

解决方法,对react-scripts进行降级处理

yarn add react-app-rewired@2.0.2-next.0

②create-react-app : 无法加载文件 C:\Users\H . Y\AppData\Roaming\npm\create-react-app.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=135170 中的 about_Execution_Policies。

解决方法:

管理员运行Windows PowerShell
输入`set-ExecutionPolicy RemoteSigned` Enter
再输入`A` Enter
最后`get-ExecutionPolicy`
再回到项目中运行create-react-app xx就可以了

2.4.6 应用中使用的组件

在这里插入图片描述

2.5 引入路由

2.5.1 下载路由

npm install --save react-router-dom

2.5.2 路由组件

containers/main/main.jsx

containers/login/login.jsx

containers/register/register.jsx

2.5.3 映射路由 index.js

import React from 'react' 
import ReactDOM from 'react-dom' 
import {HashRouter,Route,Switch} from 'react-router-dom'
import Register from './containers/regiser/regiser'
import Main from './containers/main/main'
import Login from './containers/login/login'
ReactDOM.render( (
    <HashRouter>
        <Switch>
            <Route path='/register' component={Register}></Route>
            <Route path='/login'    component={Login}></Route>
            <Route  component={Main}></Route>
        </Switch>
    </HashRouter>
), document.getElementById('root') )

2.6 引入redux

2.6.1 下载相关依赖包

npm install --save redux@3.7.2 react-redux redux-thunk
npm install --save-dev redux-devtools-extension

注意: redux 不能下载最新版本

2.6.2 reducers:redux/reducers.js

/**
 * 包含n个reducer函数:根据老的state和指定的action返回一个心的state
 */ 
import {combineReducers} from 'redux'
function xxx(state=0,action){
    return state
}
function yyy(state=0,action){
    return state
}
export default combineReducers({
    xxx,
    yyy
})
//向外暴漏的结构:{xxx:0,yyy:0}

2.6.3 store:redux/store.js

/**
 * redux最核心的管理对象模块
 */

import { createStore, applyMiddleware } from "redux";
import reducers from './reducers'
import thunk from 'redux-thunk'
import {composeWithDevTools} from 'redux-devtools-extension'
//向外暴漏store对象
export default createStore(reducers,composeWithDevTools(applyMiddleware(thunk)))

2.6.4 入口JS:index.js

import React from 'react' 
import ReactDOM from 'react-dom' 
import {HashRouter,Route,Switch} from 'react-router-dom'
import Register from './containers/register/register'
import Main from './containers/main/main'
import Login from './containers/login/login'
import {Provider} from 'react-redux'
import store from  './redux/store'
ReactDOM.render( (
  <Provider store={store}>
    <HashRouter>
            <Switch>
                <Route path='/register' component={Register}></Route>
                <Route path='/login'    component={Login}></Route>
                <Route  component={Main}></Route>
            </Switch>
        </HashRouter>
  </Provider>
), document.getElementById('root') )

2.7 注册/登录界面

2.7.1 Logo组件

1)引入logo图片

2) components/logo/logo.jsx

import React, { Component } from 'react'
import logo from './logo.png'
import './logo.less'

export default class Logo extends Component {
    render() {
        return (
            <div className="logo-container">
                <img src={logo} alt="logo" className='logo-img'/>
            </div>
        )
    }
}
  1. components/logo/logo.less
.logo-container { 
    text-align: center;
    margin-top: 10px;
    margin-bottom: 10px; .
   .logo-img { 
         width: 240px; height: 240px;
       }
  }

2.7.2 注册组件

import React, { Component } from 'react'
import {NavBar,InputItem,WingBlank,List,WhiteSpace,Radio,Button} from 'antd-mobile'
import Logo from '../../components/logo/logo'
const ListItem=List.Item
export default class Register extends Component {
    state={
        username:'', //用户名
        password:'',// 密码
        password2:'',//确认密码
        type:'dashen'//用户类型名称
    }
    register=()=>{
        console.log(this.state)
    }
    //处理输入数据的改变:更新对应的状态
    handleChange=(name,val)=>{
        //更新状态
        this.setState({
            [name]:val    //要求name变量的值   name相当于字符串,
        })
    }
    toLogin=()=>{
        this.props.history.replace('/login')
    }
    render() {
        const {type}=this.state
        return (
            <div>
                <NavBar>硅&nbsp;谷&nbsp;直&nbsp;聘</NavBar>
                <Logo/>
                <WingBlank>
                    <List>
                        <InputItem onChange={val=>{this.handleChange('username',val)}}>用户名:</InputItem>
                        <WhiteSpace/>
                        <InputItem type='password'onChange={val=>{this.handleChange('password',val)}}>密&nbsp;&nbsp;&nbsp;码:</InputItem>
                        <WhiteSpace/>
                        <InputItem type='password'onChange={val=>{this.handleChange('password2',val)}}>确认密码:</InputItem>
                        <WhiteSpace/>
                        <ListItem>
                            <span>用户类型:</span>&nbsp;&nbsp;&nbsp;
                            <Radio checked={type==='dashen'} onChange={()=>this.handleChange('type','dashen')}>大神</Radio>&nbsp;&nbsp;&nbsp;
                            <Radio checked={type==='laoban'} onChange={()=>this.handleChange('type','laoban')}>老板</Radio>
                        </ListItem>
                        <WhiteSpace/>
                        <Button type='primary' onClick={this.register}>注&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;册</Button>
                        <Button onClick={this.toLogin}>已有账户</Button>
                    </List>
                </WingBlank>
            </div>
        )
    }
}

2.7.3 登录组件

import React, { Component } from 'react'
import {NavBar,InputItem,WingBlank,List,Button,WhiteSpace} from 'antd-mobile'
import Logo from '../../components/logo/logo'
export default class Register extends Component {
    state={
        username:'', //用户名
        password:'',// 密码
    }
    login=()=>{
        console.log(this.state)
    }
    //处理输入数据的改变:更新对应的状态
    handleChange=(name,val)=>{
        //更新状态
        this.setState({
            [name]:val    //要求name变量的值   name相当于字符串,
        })
    }
    toRegister=()=>{
        this.props.history.replace('/register')
    }
    render() {
        return (
            <div>
                <NavBar>硅&nbsp;谷&nbsp;直&nbsp;聘</NavBar>
                <Logo/>
                <WingBlank>
                    <List>
                        <InputItem placeholder='请输入用户名' onChange={val=>{this.handleChange('username',val)}} >用户名:</InputItem>
                        <WhiteSpace/>
                        <InputItem placeholder='请输入密码' type='password'onChange={val=>{this.handleChange('password',val)}}>密&nbsp;&nbsp;&nbsp;码:</InputItem>
                        <WhiteSpace/>
                        <WhiteSpace/>
                        <Button type='primary' onClick={this.login}>登&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;录</Button>
                        <Button onClick={this.toRegister}>还没有账户</Button>
                    </List>
                </WingBlank>
            </div>
        )
    }
}

相关文章

网友评论

      本文标题:练习React全栈项目:招聘SPA(一)

      本文链接:https://www.haomeiwen.com/subject/ujzzzhtx.html