React

使用create-react-app搭建react + ts +

2020-12-09  本文已影响0人  三也视界

一、创建项目

npm v5.2.0引入的一条命令(npx),引入这个命令的目的是为了提升开发者使用包内提供的命令行工具的体验。

举例:使用create-react-app创建一个react项目。

老方法:

npm install -g create-react-app
create-react-app my-app

npx方式:

npx create-react-app my-app

这条命令会临时安装 create-react-app 包,命令完成后create-react-app 会删掉,不会出现在 global 中。下次再执行,还是会重新临时安装。

npx 会帮你执行依赖包里的二进制文件。

举例来说,之前我们可能会写这样的命令:

npm i -D webpack
./node_modules/.bin/webpack -v

如果你对 bash 比较熟,可能会写成这样:

npm i -D webpack
`npm bin`/webpack -v

有了 npx,你只需要这样:

npm i -D webpack
npx webpack -v

也就是说 npx 会自动查找当前依赖包中的可执行文件,如果找不到,就会去 PATH 里找。如果依然找不到,就会帮你安装!

npx 甚至支持运行远程仓库的可执行文件:

npx github:piuccio/cowsay hello

再比如 npx http-server 可以一句话帮你开启一个静态服务器!(第一次运行会稍微慢一些)

npx http-server

指定node版本来运行npm scripts:

npx -p node@8 npm run build

主要特点:

1、临时安装可执行依赖包,不用全局安装,不用担心长期的污染。
2、可以执行依赖包中的命令,安装完成自动运行。
3、自动加载node_modules中依赖包,不用指定$PATH。
4、可以指定node版本、命令的版本,解决了不同项目使用不同版本的命令的问题。

Yarn是什么?

“Yarn是由Facebook、Google、Exponent 和 Tilde 联合推出了一个新的 JS 包管理工具 ,正如官方文档中写的,Yarn 是为了弥补 npm 的一些缺陷而出现的。”这句话让我想起了使用npm时的坑了:

"5.0.3",
"~5.0.3",
"^5.0.3"

“5.0.3”表示安装指定的5.0.3版本,“~5.0.3”表示安装5.0.X中最新的版本,“^5.0.3”表示安装5.X.X中最新的版本。这就麻烦了,常常会出现同一个项目,有的同事是OK的,有的同事会由于安装的版本不一致出现bug。

带着这些坑,我开始了解Yarn的优势及其解决的问题。

Yarn的优点?

  1. 并行安装:无论 npm 还是 Yarn 在执行包的安装时,都会执行一系列任务。npm 是按照队列执行每个 package,也就是说必须要等到当前 package 安装完成之后,才能继续后面的安装。而 Yarn 是同步执行所有任务,提高了性能。
  2. 离线模式:如果之前已经安装过一个软件包,用Yarn再次安装时之间从缓存中获取,就不用像npm那样再从网络下载了。

Yarn和npm命令对比

npm yarn
npm install yarn
npm install react --save yarn add react
npm uninstall react --save yarn remove react
npm install react --save-dev yarn add react --dev
npm update --save yarn upgrade

Yarn提供了丰富的命令使你可以对Yarn包进行许多操作,包括安装、管理、发布等。

所有可用的命令都按照字母先后顺序列在此处,其中最常用的有:

image.png
npm i yarn -g
image.png image.png
yarn start 
image.png

下面的图片可知,打印出了访问该项目的两种方式(IP或者localhost)


image.png

Yarn更换源

Yarn 国内加速,修改镜像源

二、集成ant-design

在使用react项目中,不可避免的要使用蚂蚁金服出品的ant-desgin前端UI组件,ant-desgin推荐使用 craco (一个对 create-react-app 进行自定义配置的社区解决方案),对 create-react-app 的默认配置进行自定义。

https://ant.design/docs/react/use-with-create-react-app-cn

这是 create-react-app 生成的默认目录结构。

├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   └── index.html
├── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── index.css
│   ├── index.js
│   └── logo.svg
└── yarn.lock

现在从 yarn 或 npm 安装并引入 antd。

$ yarn add antd
image.png

验证antd效果

修改 src/App.js,引入 antd 的按钮组件。

import React from 'react';
import { Button } from 'antd';
import './App.css';

const App = () => (
  <div className="App">
    <Button type="primary">Button</Button>
  </div>
);

export default App;

修改 src/App.css,在文件顶部引入 antd/dist/antd.css

@import '~antd/dist/antd.css';

好了,现在你应该能看到页面上已经有了 antd 的蓝色按钮组件,接下来就可以继续选用其他组件开发应用了。其他开发流程你可以参考 create-react-app 的官方文档

我们现在已经把 antd 组件成功运行起来了!


image.png

高级配置

这个例子在实际开发中还有一些优化的空间,比如无法进行主题配置。

此时我们需要对 create-react-app 的默认配置进行自定义,这里我们使用 craco (一个对 create-react-app 进行自定义配置的社区解决方案)。

现在我们安装 craco 并修改 package.json 里的 scripts 属性。

$ yarn add @craco/craco
/* package.json */
"scripts": {
-   "start": "react-scripts start",
-   "build": "react-scripts build",
-   "test": "react-scripts test",
+   "start": "craco start",
+   "build": "craco build",
+   "test": "craco test",
}
image.png

然后在项目根目录创建一个 craco.config.js 用于修改默认配置。

/* craco.config.js */
module.exports = {
  // ...
};

自定义主题与启用less

antd 的样式使用了 Less 作为开发语言,并定义了一系列全局/组件的样式变量,你可以根据需求进行相应调整。

以下是一些最常用的通用变量,所有样式变量可以在 这里 找到。

@primary-color: #1890ff; // 全局主色
@link-color: #1890ff; // 链接色
@success-color: #52c41a; // 成功色
@warning-color: #faad14; // 警告色
@error-color: #f5222d; // 错误色
@font-size-base: 14px; // 主字号
@heading-color: rgba(0, 0, 0, 0.85); // 标题色
@text-color: rgba(0, 0, 0, 0.65); // 主文本色
@text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
@disabled-color: rgba(0, 0, 0, 0.25); // 失效色
@border-radius-base: 2px; // 组件/浮层圆角
@border-color-base: #d9d9d9; // 边框色
@box-shadow-base: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
  0 9px 28px 8px rgba(0, 0, 0, 0.05); // 浮层阴影

按照 配置主题 的要求,自定义主题需要用到类似 less-loader 提供的 less 变量覆盖功能。我们可以引入 craco-less 来帮助加载 less 样式和修改变量。

首先把 src/App.css 文件修改为 src/App.less,然后修改样式引用为 less 文件。

/* src/App.js */
- import './App.css';
+ import './App.less';
/* src/App.less */
- @import '~antd/dist/antd.css';
+ @import '~antd/dist/antd.less';

然后安装 craco-less 并修改 craco.config.js 文件如下。

$ yarn add craco-less
image.png
const CracoLessPlugin = require('craco-less');

module.exports = {
  plugins: [
    {
      plugin: CracoLessPlugin,
      options: {
        lessLoaderOptions: {
          lessOptions: {
            modifyVars: { '@primary-color': '#1DA57A' },
            javascriptEnabled: true,
          },
        },
      },
    },
  ],
};
image.png

这里利用了 less-loadermodifyVars 来进行主题配置,变量和其他配置方式可以参考 配置主题 文档。修改后重启 yarn start,如果看到一个绿色的按钮就说明配置成功了。

antd 内建了深色主题和紧凑主题,你可以参照 使用暗色主题和紧凑主题 进行接入。

同样,你可以使用 react-app-rewiredcustomize-cra 来自定义 create-react-app 的 webpack 配置。

ejec

你也可以使用 create-react-app 提供的 yarn run eject 命令将所有内建的配置暴露出来。不过这种配置方式需要你自行探索,不在本文讨论范围内。

public/index.html

image.png

使用create-react-app创建一个简单的react项目,会在项目的根目录下生成一个入口文件index.js,其内容大致如下:

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

上述代码中,document.getElementById("root")这句就是把根组件挂载在根页面中,该页面位于项目的根目录public/index.html,其内容大致如下:

<body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
</body>

上述代码中,<div id="root"></div>和document.getElementById("root")相对应.

image.png image.png

App.js布局

<Layout>
      <Sider>Sider</Sider>
      <Layout>
        <Header>Header</Header>
        <Content>Content</Content>
        <Footer>Footer</Footer>
      </Layout>
    </Layout>

搜索使用API


image.png

查看API使用


image.png

引入使用包的部分插件

import {HomeOutlined, ProjectOutlined, AppstoreAddOutlined, PicCenterOutlined, TeamOutlined, ShopOutlined,FileAddOutlined} from '@ant-design/icons'
import {Layout, Menu} from "antd";

const {Sider} = Layout;
const {SubMenu} = Menu;

这里需要注意的是{}里面的大小写需要注意,比如const {SubMenu} = Menu;里面的SubMenu,写成了Submenu,并不会报错,但是编译运行的时候,


image.png
image.png

改成SubMenu重新编译即可。
这里其实可以先写const {} = Menu;然后在输入SubMenu的时候会有提示的,这样可以避免输入错误

基于react-router-dom实现路由模块

https://reactrouter.com/

yarn add react-router-dom
image.png

index.js <React.StrictMode> 报错

在使用了SubMenu之后,点击二级菜单会有警告,如下,去掉严苛模式即可


image.png

index.js <React.StrictMode> 替换为<BrowserRouter>

import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>
   ,
    document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

App.js 配置导航路由

import {
  BrowserRouter as Router,
  Switch,
  Route,
  Link
} from "react-router-dom";

确定路由位置

image.png
 <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/topics">
            <Topics />
          </Route>
          <Route path="/">
            <Home />
          </Route>
</Switch>

创建页面组件

image.png

index.js

import React from 'react';
import './index.less';

export  default class Index extends React.Component{

    render() {
        return <div className='add'>
            category Add
        </div>;
    }
}

index.less

.add{
  background-color: brown;
}

App.js 导入界面引用

import Home from './page/index';
import User from './page/user/index';
import AddCategory from './page/category/add/index';
import Category from './page/category/index';

import AddConfig from './page/config/add/index';
import Config from './page/config/index';

App.js 添加界面路由

import './App.less';
import React from "react";
import {Layout} from "antd";
import DrawerMenu from "./Component/DrawerMenu";
import Header from "./Component/Header";
import {
    BrowserRouter as Router,
    Switch,
    Route,
    Link
} from "react-router-dom";
import Home from './page/index';
import User from './page/user/index';
import AddCategory from './page/category/add/index';
import Category from './page/category/index';

import AddConfig from './page/config/add/index';
import Config from './page/config/index';

const {Content,Footer}=Layout;

class App extends React.Component{

    state = {
        title:'首页',
        collapsed: false
    };
    render() {
        const {collapsed, title} = this.state;
        return (
            <Layout className='App'>
                <DrawerMenu collapsed={collapsed} />
                <Layout>
                    <Header title={title} toggle={(collapsed) => {
                        this.setState({collapsed});
                    }}/>
                    <Content className='App-content'>
                        <Switch>
                            <Router path='/' component={Home}/>
                            <Router path='/category' component={Category}/>
                            <Router path='/category-add' component={AddCategory}/>
                            <Router path='/config' component={Config}/>
                            <Router path='/config-add' component={AddConfig}/>
                            <Router path='/user' component={User}/>
                        </Switch>
                    </Content>
                    <Footer className='App-footer'>Yatsar美容仪管理后台 @2020 Created by
                        <a herf="https://www.baidu.com"> 享维</a>
                    </Footer>
                </Layout>
            </Layout>
        );
    }


}

export default App;


完成跳转

跳转主要在左侧的抽屉菜单栏(DrawerMenu.js)点击实现切换逻辑

withRouter 高阶组件使用


image.png
import { withRouter } from "react-router";

···

//withRouter是react-router的一个高阶组件,获取history
//render时会把match,location和history传入props
export  default withRouter(Index);
react-router 的history实现跳转路由
image.png

封装路由跳转

引入react-native-event-bus,主要解决页面跳转之后的数据交互和更新

yarn add react-native-event-bus

发送导航消息

    EventBus.getInstance().fireEvent(ROUTE_CHANGE, {goto: route});
import EventBus from "react-native-event-bus";

export const RouteConfig={
    home:{
        key:'home',
        title:'首页',
        pathname: '/'
    },
    user:{
        key:'user',
        title: '用户管理',
        pathname: '/user'
    },
    category:{
        key:'category',
        title:'商品类别',
        pathname: '/category'
    },
    addCategory:{
        key:'addCategory',
        title:'添加商品类别',
        pathname: '/category-add'
    },
    configList:{
        key:'configList',
        title:'配置列表',
        pathname: '/config'
    },
    configAdd:{
        key:'configAdd',
        title:'添加配置',
        pathname: '/config-add'
    }
};

export const ROUTE_CHANGE = 'routeChange';

export default class NavigationUtil{
    static goto(route, history){
        const {pathname} = route;
        if (!history || !pathname) {
            console.log('history && pathname cannot be null.')
        }
        //发送导航消息
        EventBus.getInstance().fireEvent(ROUTE_CHANGE, {goto: route});
        return params => {
            history.push({
                pathname,
                ...(params || {})
            })
        }
    }
}

实现表格和数据分页

效果展示


image.png

Table表格

image.png

Pagination分页

image.png

开关Switch

image.png
Popconfirm

气泡确认框 Popconfirm

image.png image.png

表单Form

通过 filterDropdown 自定义的列筛选功能,并实现一个搜索列的示例。


image.png

https://ant.design/components/table-cn/#components-table-demo-custom-filter-panel

image.png

react-highlight-words

多种布局


image.png image.png

警告弹窗


image.png

react-native-event-bus

验证项目是否正常

后台springboot打包之后,war包放到服务器的tomcat的webapps目录

image.png
查看当前tomcat服务的端口号
image.png
这里没有修改的话,默认是-1,既端口号是8080
baseurl为本地,webapp的war包解压后的文件夹名字为demo-0.0.1。既服务器地址为http://localhost:8080/demo-0.0.1 所以前端代码对应的api请求地址的baseurl应该相对应
export const url = "http://127.0.0.1:8080/demo-0.0.1";
image.png

对应swagger网址为
http://localhost:8080/demo-0.0.1/swagger-ui.html

请求某个一接口,查看url

image.png
http://127.0.0.1:8080/demo-0.0.1与上面的相对应

打开前端界面


image.png
上一篇下一篇

猜你喜欢

热点阅读