【前端新手也能做大項目】:跟我一起,從零打造一個屬於自己的在線Visio項目實戰【ReactJS + UmiJS + DvaJS】(二)

本系列教程是教大家如何根據開源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. 最後,畫布接口參考開發文檔

www.yuque.com/alsmile/top…

二、react組件間通信 - 右上角狀態欄

 

file

 

 

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: 0. 閱讀開發文檔,瞭解相關屬性。

  1. fork倉庫到自己名下
  2. 本地修改並提交到自己的git倉庫
  3. 在自己的fork倉庫找到 “Pull request” 按鈕,提交file

其他

右鍵菜單和其他功能頁面待續。

開源項目不易,歡迎大家一起參與,或資助服務器:

 

file


著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章