react实战系列 —— 起步(mockjs、第一个模块、docusaurus)
其他章节请看:
起步
本篇我们首先引入 mockjs ,然后进入 spug 系统,接着模仿”任务计划“模块实现一个类似的一级导航页面(”My任务计划“),最后玩一下 Facebook 的 docusaurus,将 spug 官网文档在本地跑起来。
Tip:环境准备请看 上文
mockjs
点击登录,提示“请求异常: Network Error”。因为没有后端提供接口。
笔者使用 mockjs
来绕过,进入系统。
添加 mockjs 只需要三步。
首先安装依赖:
spug-study> npm i -D mockjs@1
added 1 package, and audited 1789 packages in 54s
107 packages are looking for funding
run `npm fund` for details
33 vulnerabilities (1 low, 16 moderate, 15 high, 1 critical)
To address issues that do not require attention, run:
npm audit fix
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
然后新建 src/mock/index.js
,内容如下:
import Mock from 'mockjs'
// 开发环境引入 mock
if (process.env.NODE_ENV === 'development') {
Mock.mock('/api/account/login/', 'post', {
"data": { "id": 1, "access_token": "5bb076db06fd4001b85d12e44ab96c56", "nickname": "\u7ba1\u7406\u5458", "is_supper": true, "has_real_ip": true, "permissions": [] }, "error": ""
})
}
最后在 src/index.js
中引入 mock:
+ import './mock'
重启服务,再次点击点击“登录”,即可进入系统:
Tip:spug 提供了“演示预览”,只需要关注即可获取体验账号,上面的 mock 数据就是这么来的。
注:mockjs 这种使用方式,在浏览器开发界面是看不到 ajax 请求的。倘若想看到 ajax 请求,你可以把 mockjs 配合 node 的 express 使用,mockjs 仅仅当作造数据的工具,url 匹配就交由 express 处理。
任务计划
”任务计划“页面分为两部分:上面用于过滤、下面是表格:
My任务计划
模仿”任务计划“,最终效果如下:
点击“开始执行”和刷新表格,“更新于“中的模拟时间都会变化。
代码如下:
新增导航”M任务计划“:
// src/routes.js
import ScheduleIndex from './pages/schedule';
+ import MyScheduleIndex from './pages/myschedule';
{
icon: <ScheduleOutlined/>,
title: '任务计划',
auth: 'schedule.schedule.view',
path: '/schedule',
component: ScheduleIndex
},
+ {
+ icon: <ScheduleOutlined/>,
+ title: 'M任务计划',
+ auth: 'myschedule.myschedule.view',
+ path: '/myschedule',
+ component: MyScheduleIndex
+ },
增加 mock 数据:
// src/mock/index.js
// 开发环境引入 mock
if (process.env.NODE_ENV === 'development') {
Mock.mock('/api/schedule/', 'get', {
"data": { "types": ["每天执行"], "tasks": [{ "id": 1, "name": "\u6e05\u7406\u8ba2\u5355\u6570\u636e", "type": "\u6bcf\u5929\u6267\u884c", "command": "echo '\u6e05\u7406\u8ba2\u5355\u6570\u636e'", "targets": ["local"], "trigger": "cron", "trigger_args": { "rule": "0 1 * * *", "start": null, "stop": null }, "is_active": true, "desc": null, "latest_id": null, "rst_notify": { "mode": "0" }, "created_at": "2021-04-28 12:07:56", "created_by_id": 1, "updated_at": "2021-04-28 12:19:16", "updated_by_id": 1, "latest_status": null, "latest_run_time": null, "latest_status_alias": null }] }, "error": ""
})
Mock.mock('/api/myschedule/', 'get', () => ({
"data": [{ "id": 1, "name": "项目A", machine: '192.168.1.3', time: new Date().toLocaleTimeString(), status: '进行中'}],
"error": ""
}))
// 点击“开始执行”
Mock.mock(/\/api\/myschedule.*/, 'post', () => ({
data: { test: 'test' }, error: ''
}))
}
增加 myschedule 路由组件。共 3 个文件,内容如下:
// src/pages/myschedule/index.js
import React from 'react';
import { observer } from 'mobx-react';
import { Select, Button } from 'antd';
import { SearchForm, AuthDiv, Breadcrumb } from 'components';
import ComTable from './Table';
import store from './store';
export default observer(function () {
return (
<AuthDiv auth="myschedule.myschedule.view">
<Breadcrumb>
<Breadcrumb.Item>首页</Breadcrumb.Item>
<Breadcrumb.Item>M任务计划</Breadcrumb.Item>
</Breadcrumb>
<SearchForm>
<SearchForm.Item span={6} title="项目">
<Select allowClear value={store.name} onChange={v => store.name = v} placeholder="请选择">
<Select.Option value="p1">项目1</Select.Option>
<Select.Option value="p2">项目2</Select.Option>
<Select.Option value="p3">项目3</Select.Option>
<Select.Option value='p4'>项目4</Select.Option>
</Select>
</SearchForm.Item>
<SearchForm.Item span={6} title="机器">
<Select allowClear value={store.machine} onChange={v => store.machine = v} placeholder="请选择">
<Select.Option value='m1'>机器1</Select.Option>
<Select.Option value='m2'>机器2</Select.Option>
<Select.Option value='m3'>机器3</Select.Option>
<Select.Option value='m4'>机器4</Select.Option>
</Select>
</SearchForm.Item>
<Button type="primary" onClick={store.build}>开始执行</Button>
</SearchForm>
<ComTable />
</AuthDiv>
)
})
// src/pages/myschedule/store.js
import { observable, computed } from 'mobx';
import http from 'libs/http';
class Store {
// 表格数据
@observable records = [];
// 是否正在请求数据
@observable isFetching = false;
// 计算属性
// 数据源
@computed get dataSource() {
return this.records
}
fetchRecords = () => {
this.isFetching = true;
http.get('/api/myschedule/')
.then(res => this.records = res)
.finally(() => this.isFetching = false)
};
build = () => {
const params = {
name: this.name,
machine: this.machine
}
console.log('params', params)
http.post('/api/myschedule', {params})
.then(res => {
this.fetchRecords()
})
}
}
export default new Store()
// src/pages/myschedule/Table.js
import React from 'react';
import { observer } from 'mobx-react';
import { Tag } from 'antd';
import { Action, TableCard } from 'components';
import store from './store';
@observer
class ComTable extends React.Component {
componentDidMount() {
store.fetchRecords()
}
colors = ['orange', 'green', 'red'];
columns = [{
title: '项目',
dataIndex: 'name',
}, {
title: '机器',
dataIndex: 'machine',
}, {
title: '更新于',
dataIndex: 'time',
}, {
title: '最新状态',
render: info => {
return <Tag color="blue">{info.status}</Tag>
},
}, {
title: '操作',
width: 180,
render: info => (
<Action>
<Action.Button disabled>详情</Action.Button>
</Action>
)
}];
render() {
return (
<TableCard
// tKey 必须唯一?
tKey="msi"
rowKey="id"
title="M任务列表"
loading={store.isFetching}
dataSource={store.dataSource}
onReload={store.fetchRecords}
pagination={{
showSizeChanger: true,
showLessItems: true,
showTotal: total => `共 ${total} 条`,
pageSizeOptions: ['10', '20', '50', '100']
}}
columns={this.columns} />
)
}
}
export default ComTable
docusaurus
spug 的官网文档采用 Facebook 的 docusaurus(快速
构建 高效
的网站,专注处理 内容
) 来构建的。
我们可以将 spug 的文档在克隆到本地。步骤如下:
$ git clone https://github.com/JackieLieu/spug.dev.git spug-docs
Cloning into 'spug-docs'...
remote: Enumerating objects: 525, done.
Receiving objects: 73% (384/5remote: Total 525 (delta 0), reused 0 (delta 0), pack-reused 525
Receiving objects: 100% (525/525), 458.97 KiB | 420.00 KiB/s, done.
Resolving deltas: 100% (317/317), done.
进入 spug-docs/website
,查看目录:
spug-docs/website (master)
$ ll
total 21
drwxr-xr-x 1 78614 197609 0 4月 17 17:58 blog/
drwxr-xr-x 1 78614 197609 0 4月 17 17:58 core/
-rw-r--r-- 1 78614 197609 390 4月 17 17:58 package.json
drwxr-xr-x 1 78614 197609 0 4月 17 17:58 pages/
-rw-r--r-- 1 78614 197609 4258 4月 17 17:58 README.md
-rw-r--r-- 1 78614 197609 1289 4月 17 17:58 sidebars.json
-rw-r--r-- 1 78614 197609 3567 4月 17 17:58 siteConfig.js
drwxr-xr-x 1 78614 197609 0 4月 17 17:58 static/
安装依赖:
PS website> cnpm i
√ Installed 1 packages
√ Linked 845 latest versions
[1/6] scripts.postinstall docusaurus@1.14.7 › imagemin-jpegtran@6.0.0 › jpegtran-bin@^4.0.0 run "node lib/install.js", root: "spug-docs\\website\\node_modules\\_jpegtran-bin@4.0.0@jpegtran-bin"
√ jpegtran pre-build test passed successfully
[1/6] scripts.postinstall docusaurus@1.14.7 › imagemin-jpegtran@6.0.0 › jpegtran-bin@^4.0.0 finished in 954ms
[2/6] scripts.postinstall docusaurus@1.14.7 › imagemin-gifsicle@6.0.1 › gifsicle@^4.0.0 run "node lib/install.js", root: "spug-docs\\website\\node_modules\\_gifsicle@4.0.1@gifsicle"
√ gifsicle pre-build test passed successfully
[2/6] scripts.postinstall docusaurus@1.14.7 › imagemin-gifsicle@6.0.1 › gifsicle@^4.0.0 finished in 751ms
...
[6/6] scripts.postinstall docusaurus@1.14.7 › tree-node-cli@1.5.2 › fast-folder-size@^1.6.1 run "node get-sysinternals-du.js", root: "spug-docs\\website\\node_modules\\_fast-folder-size@1.6.1@fast-folder-size"
...
deprecate docusaurus@1.14.7 › markdown-toc@1.2.0 › remarkable@1.7.4 › autolinker@0.28.1 › gulp-header@^1.7.1 Removed event-stream from gulp-header
√ All packages installed (973 packages installed from npm registry, used 59s(network 38s), speed 148.83kB/s, json 846(5.51MB), tarball 0B)
启动项目:
PS spug-docs\website> npm run start
> start
> docusaurus-start
Failed to start live reload server: RangeError: Maximum call stack size exceeded
LiveReload server started on port 35729
Docusaurus server started on port 3001
注:docusaurus 官网提到系统要求是 node >= 14
,笔者尝试用 node 14 编译 spug-docs,报各种错误,最后尝试 node 16,却成功了。
spug 与内网
倘若你要在内网中使用 spug,你可能会遇到如下问题:
cnpm 导致压缩失败
将 node_modules 压缩拷贝,如果安装 spug 的依赖使用的是 cnpm i
,可能会压缩失败(笔者尝试使用了各种压缩工具),可以改用 npm i
。
win7
如果你的环境是 win7,那么 node 最多只能安装 node 14
以下的版本,笔者使用 v13.14
。
而 node 12
是不能对 spug 项目进行构建的。
其他章节请看:
react实战系列 —— 起步(mockjs、第一个模块、docusaurus)的更多相关文章
- react实战系列 —— 我的仪表盘(bizcharts、antd、moment)
其他章节请看: react实战 系列 My Dashboard 上一篇我们在 spug 项目中模仿"任务计划"模块实现一个类似的一级导航页面("My任务计划") ...
- react实战 系列 —— React 的数据流和生命周期
其他章节请看: react实战 系列 数据流和生命周期 如何处理 React 中的数据,组件之间如何通信,数据在 React 中如何流动? 常用的 React 生命周期方法以及开源项目 spug 中使 ...
- react实战系列 —— React 中的表单和路由的原理
其他章节请看: react实战 系列 React 中的表单和路由的原理 React 中的表单是否简单好用,受控组件和非受控是指什么? React 中的路由原理是什么,如何更好的理解 React 应用的 ...
- react实战系列 —— react 的第一个组件
react 的第一个组件 写了 react 有一个半月,现在又有半个月没写了,感觉对其仍旧比较陌生. 本文分两部分,首先聊一下 react 的相关概念,然后不使用任何语法糖(包括 jsx)或可能隐藏底 ...
- React 实战系列:模块化
本系列以实战为主,通过一个 TODO 应用来学习深入 React. 学习无捷径,唯一的办法就是 coding!coding!coding! 如有不足之处,欢迎大家批评指正,共同进步! 言毕,开始撸
- Nodejs实战系列:数据加密与crypto模块
博客地址:<NodeJS模块研究 - crypto> Github :https://github.com/dongyuanxin/blog nodejs 中的 crypto 模块提供了各 ...
- React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发
React Native实战系列教程之自定义原生UI组件和VideoView视频播放器开发 2016/09/23 | React Native技术文章 | Sky丶清| 4 条评论 | 1 ...
- Java秒杀系统实战系列~构建SpringBoot多模块项目
摘要:本篇博文是“Java秒杀系统实战系列文章”的第二篇,主要分享介绍如何采用IDEA,基于SpringBoot+SpringMVC+Mybatis+分布式中间件构建一个多模块的项目,即“秒杀系统”! ...
- CODING DevOps 微服务项目实战系列第一课,明天等你
CODING DevOps 微服务项目实战系列第一课<DevOps 微服务项目实战:DevOps 初体验>将由 CODING DevOps 开发工程师 王宽老师 向大家介绍 DevOps ...
随机推荐
- 修改vue的url
1.修改router的index.js文件,增加base url的配置 2.修改config的index.js文件. bulid的index,assetsRoots和assetsPublicPath的 ...
- python编程笔记--字符编码
ASCII码.Unicode.utf-8 ASCII(American Standard Code for Information Interchange,美国标准信息交换代码)是基于拉丁字母的一套电 ...
- vivo 商品中台的可视化微前端实践
一.背景 在电商领域内,商品是一个重要组成部分,与其对应的商品管理系统,则负责商品的新建.编辑.复制等功能.随着商品管理系统的成熟稳定和业务上的扩展需求,催化出了商品中台的诞生.它可以将现有商品功能最 ...
- 哪些是重要的bean生命周期方法? 你能重载它们吗?
有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用.第二个方法是 teardown 它是在容器卸载类的时候被调用. The bean 标签有两个重要的属性 ...
- 时间工具类之“ JDK1.8中 LocalDate、LocalTime、LocalDateTime、LocalDateTimeUtil四个时间工具类”
一.使用的原因 在JDK8发布的时候,推出了LocalDate.LocalTime.LocalDateTime这个三个时间处理类,以此来弥补之前的日期时间类的不足,简化日期时间的操作. 在Java8之 ...
- SQL数据库之设置查询出来数据为默认值
-- 如果工资为null,按0处理 -- 函数: ifnull(字段, 默认值) : 如果指定字段的内容是null, 就按默认值处理 select name, ifnull(salary, 0) fr ...
- 5_系统的可控性_Controllability
- vue常用知识点总结
感谢本文引用链接的各位大佬们,小菜鸟我只是个搬运工 1.谈一谈你理解的vue是什么样子的? vue是数据.视图分离的一个框架,让数据与视图间不会发生直接联系.MVVM 组件化:把整体拆分为各个可以复用 ...
- python-你好
你的程序会读入一个名字,比如John,然后输出"Hello John". 输入格式: 一行文字. 输出格式: 一行文字. 输入样例: Mary Johnson 输出样例: Hell ...
- java中输出一个字符串里面的空格,字母还有数字的数目举例说明
9.6 About string,"I am a teacher",这个字符串中有多少个字,且分别把每个字打印出来. /*本题的思路就是,当我有一个字符串,我需要一个一个字符的处理 ...