TS+react开发笔记3:从antd-demo-ts开始编写react程序

由于项目需求,需使用typescript + react进行开发。事实上这也是国内许多大厂的前端方案。其中TypeScript是为了规范代码结构,这个东西不难,只要学了面向对象编程和javascript就很容易看懂。用react的目的是可以分层地编写复杂的前端UI。
初学这套方案,建议从TypeScript-React-Starter这个项目开始.该项目是一个种子程序,安装好以后TS、react代码都是自动编译,其中内置有nodejs服务器来完成这一点,你只需要写代码就行了,TS编译啥的完全都不用管,连配置webstorm都省略了。

不过TypeScript-React-Starter作为种子程序具体的功能内容,再加上react库本身规模很小只解决视图层的一些问题,所以为了避免很多重复造轮子的工作,需要与很多其他优秀组件合用。常用组件大致分这么几类:

UI组件:

  • ant design,这是国内用的最多的react UI库,更新频率高,有大厂背书
  • Material-UI,google设计标准的国际化UI库,在github上也很有人气

可视化组件:

  • recharts,  react + D3

CURD项目开发:

  • react-redux, 前端的数据存储和状态管理,类似MVVM框架的model-view层,可以理解为有了react-redux才能做类似angularjs的数据绑定。
  • react-router, 前端路由,如果你的单页应用事实上有很多页面组成的话需要这个

......

react组件特别多,在此不可能一一赘述,更多的详见:react组件专题Awesome 。必须指出的是,选用什么组件关键看项目需求,切忌为了追求高大上就在项目一开始就把看着NB的库全用上,这除了造成加班并不会有什么好处。

但是UI组件几乎是必用的。因此肯定要选定一个UI组件。我这里选择了ant design,主要是因为文档多讨论的多,这样遇到问题容易解决。再加上我要做的项目需求是一个用于科研的图形布局试验程序,所以还需要个paper.js。所以项目初始阶段需要的库或框架也就下面这些:

  • typescript
  • react
  • ant design
  • paper.js

所以我们项目初始化使用yarn安装create-react-app 且包含antd,安装过程官网虽然有说,但我安装的时候遇到了一些坑。为了后来人能轻松一些,现记录如下:

本人电脑环境:
系统:windows 10
nodejs: v12.14.1 (相对上一篇文章,我卸载重装了最新版的nodejs)
npx: v6.13.4

1.首先安装yarn

别安装yarn 2.0.0以上版本,因为在后面的步骤会遇到bug,所以在2.0.0版本成熟之前,我建议还是安装1.x版本。1.x最新版本安装方式如官网所示。我是直接运行命令:

npm install -g yarn

然后查看yarn版本确保无误。

yarn -v

yarn换淘宝源,国内使用的话最好还是换一下源,不然极其舒爽。

yarn config set registry http://registry.npm.taobao.org/

yarn查看目前使用的源

yarn config get registry

最终我安装好的yarn版本是1.21,使用淘宝源。

2. 安装create-react-app的antd版本。

前文介绍过,create-react-app跟TypeScript-React-Starter类似,也是自带nodejs脚本开发免编译的种子程序。可以指定带tpyescript模板的版本。

yarn create react-app antd-demo-ts --template typescript

试验安装成功与否

cd antd-demo-ts
yarn start

3. 安装antd

yarn add antd

接着按照官网所示例子测试到最后即可, 我把包括按需加载步骤都完成了。

调试完成官网例子以后,就可以开始写自己的代码了。不过在这之前最好把react的chrome开发人员工具装上,这样可以在F12开发人员工具当中看到一个react选项,直接看到react组件嵌套结构,而不是对着一堆html代码发呆了。这个工具在谷歌应用商店里有,叫react-dev-tool,由于近期网络问题我实在上不去谷歌商店。就下载了此工具的源码编译安装了。具体操作跟下面这个文档差不多:https://www.jianshu.com/p/8afd06135fd5   (注意,现在版本更新了,不能完全照着这个文档来,需要在第一步git下载源码时时切换为V3分支, 编译后使用第二种方法“加载已解压扩展程序”方式安装)

4. 接下来我们试着修改这个官网例子,添加一些antd的其他组件。

基本上是参考antd官网例子,另外网上相关教程很多,这一步比较简单。例如我参考的是这个教程:https://www.yuque.com/ant-design/course/layout,通过修改App.tsx文件添加一些布局上的内容:

import React, { Component } from 'react';
import { Layout, Menu, Icon } from 'antd';
import './App.css';
const { Header, Footer, Sider, Content } = Layout;
const SubMenu = Menu.SubMenu;


class App extends Component {
  render() {
    return (
      <Layout>
        <Sider width={256} style={{ minHeight: '100vh' }}>
          <div style={{ height: '32px', background: 'rgba(255,255,255,.2)', margin: '16px'}}/>
          <Menu theme="dark" mode="inline" defaultSelectedKeys={['1']}>
            <Menu.Item key="1">
                <Icon type="pie-chart" />
                <span>Helloworld</span>
            </Menu.Item>
            <SubMenu
              key="sub1"
              title={<span><Icon type="dashboard" /><span>Dashboard</span></span>}
            >
               <Menu.Item key="2">分析页</Menu.Item>
               <Menu.Item key="3">监控页</Menu.Item>
               <Menu.Item key="4">工作台</Menu.Item>
            </SubMenu>
          </Menu>
        </Sider>
        <Layout >
          <Header style={{ background: '#fff', textAlign: 'center', padding: 0 }}>Header</Header>
          <Content style={{ margin: '24px 16px 0' }}>
            <div style={{ padding: 24, background: '#fff', minHeight: 360 }}>
              {this.props.children}
            </div>
          </Content>
          <Footer style={{ textAlign: 'center' }}>Ant Design ©2018 Created by Ant UED</Footer>
        </Layout>
      </Layout>
    );
  }
}

export default App;

这是添加了名为一系列组件,包括Layout, Menu, Icon。成功。

5. 试着添加一些非antd组件。

出于项目需要,我们要使用一个名为React Split Pane的组件,把首页分为几个部分。这个插件在antd官网有介绍,其git目录如下:https://github.com/tomkp/react-split-pane

按照其git页面的提示,先yarn安装该组件。

yarn add react-split-pane

然后这个React Split Pane怎么用呢?当然是得看https://github.com/tomkp/react-split-pane得readme,通过看readme知道了大致引入方式,将原来的例子删光(打扫完房间再请客不容易磕磕绊绊),然后仿照readme的里的例子重新做一个,代码大致如下:

import React, { Component } from 'react';
import { Layout, Menu, Icon } from 'antd';
import SplitPane from 'react-split-pane';
import './App.css';
const { Header, Footer, Sider, Content } = Layout;
const SubMenu = Menu.SubMenu;

class App extends Component {
  render() {
    return (
      <SplitPane split="vertical" minSize={50} defaultSize={100}>
        <div />
        <div />
      </SplitPane>
    );
  }
}

export default App;

试验后发现很成功。接下来我们结合Layout, Menu, Icon组件和这个React Split Pane组件。我们的目标是实现画图版程序的基本布局,大概长下面这样:

代码如下:

import React, { Component } from 'react';
import { Layout, Menu, Icon } from 'antd';
import SplitPane from 'react-split-pane';
import './App.css';
const { Header, Sider, Content } = Layout;
const SubMenu = Menu.SubMenu;

function App(){
  return (
    <Layout className="me-layout">
      <Header>
        Header
      </Header>
      <Layout>
        <Sider width={48} className="me-left-bar">
          Sider
        </Sider>
        <Content className="me-canvas">
        </Content>
        <Content className="me-right-bar">
          <SplitPane
            defaultSize="60%"
            split="horizontal"
            style={{position: 'static'}}
            resizerStyle={{padding:'5px'}}
            paneStyle={{ background: '#eee' }}
            pane2Style={{ background: '#aaa4ba' }}
          >
            <div />
            <div />
          </SplitPane>
        </Content>
      </Layout>
    </Layout>
  );
}

export default App;

此外,App.css也需要修改:

/*me*/
#root {
  height:100%;
  width:100%;
}
.me-layout{
  height: 100%;
}
header {
  color: #fff;
}
.me-left-bar{
  min-height: 100%; 
  width: 48px;
  color: white;
  background: #666
}
.me-canvas {
    min-height: 100%;
    background: #f8f8f8; 
    width: 70%;
    border: 1px red solid;
}
.me-right-bar{
  min-height: 100%;
    background: #f8f8f8; 
    width: 30%;
    border: 1px green solid;
}

/*react-split-pane*/
.Resizer {
  background: #000;
  opacity: 0.2;
  z-index: 1;
  -moz-box-sizing: border-box;
  -webkit-box-sizing: border-box;
  box-sizing: border-box;
  -moz-background-clip: padding;
  -webkit-background-clip: padding;
  background-clip: padding-box;
}

.Resizer:hover {
  -webkit-transition: all 2s ease;
  transition: all 2s ease;
}

.Resizer.horizontal {
  height: 11px;
  margin: -5px 0;
  border-top: 5px solid rgba(255, 255, 255, 0);
  border-bottom: 5px solid rgba(255, 255, 255, 0);
  cursor: row-resize;
  width: 100%;
}

.Resizer.horizontal:hover {
  border-top: 5px solid rgba(0, 0, 0, 0.5);
  border-bottom: 5px solid rgba(0, 0, 0, 0.5);
}

.Resizer.vertical {
  width: 11px;
  margin: 0 -5px;
  border-left: 5px solid rgba(255, 255, 255, 0);
  border-right: 5px solid rgba(255, 255, 255, 0);
  cursor: col-resize;
}

.Resizer.vertical:hover {
  border-left: 5px solid rgba(0, 0, 0, 0.5);
  border-right: 5px solid rgba(0, 0, 0, 0.5);
}
.Resizer.disabled {
  cursor: not-allowed;
}
.Resizer.disabled:hover {
  border-color: transparent;
}

OK,以上目标就完成了。

7.为了后面工作的前准备:修改自己项目的端口号避免端口占用问题

由于我这里已经下载并运行了好几个基于creat-react-app的程序,为了避免端口上的冲突,我先把自己的react-antd-ts项目端口修改了一下。先在项目工程目录下安装名为cross-env的插件:

yarn add cross-env

然后修改package.json文件的"scripts",增加如下方红色字所示内容:

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

最后yarn start, 项目就从localhost:4321运行了。