前端新手也能做大项目跟我一起从零打造一个属于自己的在线Visio项目实战ReactJS二

34次阅读

共计 2403 个字符,预计需要花费 7 分钟才能阅读完成。

本系列教程是教大家如何根据开源 js 绘图库,打造一个属于自己的在线绘图软件。当然,也可以看着是这个绘图库的开发教程。如果你觉得好,欢迎点个赞,让我们更有动力去做好!

本系列教程重点介绍如何开发自己的绘图软件,因此,react 基础和框架不在此介绍。可以推荐 react 官网学习,或《React 全家桶免费视频》。

本系列教程源码地址:Github

前面教程一,搭建了一个基础框架,现在我们来实现 顶部导航菜单栏 功能。

一、react 组件间通信 – 菜单事件

这里,我们通过 redux 方式来实现组件间消息通信。UmiJS 做了一点封装,使用更简单。

1. 新建 store – model

我们在 src/models 文件夹下新建 event.ts 文件,专门用于消息事件的 store 处理。
主要包含:

  • namespace – 命名空间
  • state – 数据
  • reducers – 数据搬运工

给没有接触过 redux 的同学简单介绍下,会的请自动跳过:
models 是数据存储的地方。用 namespace 来进行模块划分或避免命名冲突;state:类似于 react 的 state,专门用于存放数据;reducers:接收更新命令,根据命令参数 (state:原数据;action:新行为参数数据),然后加上自己的业务逻辑,去实现如何更新数据。比如下面,只是简单的赋值,没有额外的业务逻辑。
注意,有个硬性规定就是,reducers 要返回一个新数据副本,而不是直接修改 models 里面的 state。因此,这里 return 下面的第一行(…state)就是先拷贝原始 state 所有属性,然后第二、三行,赋值新数据。

reducers: {emit(state, action) {
      return {
        ...state,
        event: action.payload.event,
        data: action.payload.data,
      };
    },
  },

2. 在 onMenuClick 里,用 dispatch 发送修改数据命令

UmiJs + DvaJS 已经自动封装 dispatch 到 react 的 props 里了,我们直接拿来使用。
目前为止,我们的菜单事件很简单,没有额外数据,我们就直接 dispatch 发生菜单命令(key 值)就好。
其中,type 表示在 store 的所有 reducers(不仅仅是上面的 model,还包含其他所有 model)中查找用哪个函数处理数据,格式:命名空间(event)/reducers 函数(emit)。payload,更新数据用的参数。

this.props.dispatch({
            type: 'event/emit',
            payload: {event: key}
});

3. 在需要接收菜单消息的 page 页面,connect 连接绑定数据

  1. 导入连接函数:import {connect} from ‘dva’;
  2. 绑定 connect:在 pages/index.tsx 底部添加:
export default connect((state: any) => ({event: state.event}))(Index);

上面,state:any 是指整个 store,我们这里暂时只用到 event,故只返回 event 加入到 pages/index 的 props。

4. 在 page 页面 componentDidUpdate,接收消息

componentDidUpdate() {if (this.props.event !== this.state.event) {this.setState({ event: this.props.event});
      if (this['handle_' + this.props.event.event]) {this['handle_' + this.props.event.event](this.props.event.data);
      }
    }
  }

我们先判断消息是否已经处理过,避免无限循环。然后交给具体函数处理。

5. 最后,画布接口参考开发文档

https://www.yuque.com/alsmile…

二、react 组件间通信 – 右上角状态栏

1. 新建 store – model

还是先新建一个 store 用于通信,src/models/canvas.data.ts。这个 model 用于全局 canvas 的数据保存。

2. 监听画布 canvas 消息,dispatch 最新状态

在 src/pages/index.ts 里,前面已经设置监听了 canvas 的消息 onMessage 函数。
现在我们添加‘resize’,‘scale’,‘locked’等事件的处理:

      case 'resize':
      case 'scale':
      case 'locked':
        if (this.canvas) {
          this.props.dispatch({
            type: 'canvas/update',
            payload: {data: this.canvas.data}
          });
        }
        break;

3. 在 layouts/headers.tsx 页面,connect 连接绑定数据

import {connect} from 'dva';

export default connect((state: any) => ({canvasData: state.canvas}))(Headers);

4. render 函数显示即可

render(): React.ReactNode {const { data} = this.props.canvasData;
    const scale = Math.floor(data.scale);
        ......
}

这里,我们没有特别业务处理,直接格式化显示即可。

三、本篇最后

顶部菜单导航栏基础功能完成。还是 欢迎大家补充并提交 GitHub 的 pr

  1. 阅读开发文档,了解相关属性。
  2. fork 仓库到自己名下
  3. 本地修改并提交到自己的 git 仓库
  4. 在自己的 fork 仓库找到“Pull request”按钮,提交

其他

右键菜单、图形列表等功能待续。

开源项目不易,欢迎大家一起参与,或资助服务器:

正文完
 0