【前端vue進階實戰】:從零打造一個流程圖、拓撲圖項目【Nuxt.js + Element + Vuex】 (二)

前面一,下面我們利用vuex實現頂部導航欄事件和右上角狀態欄。

本系列教程是用Vue.js + Nuxt.js + Element + Vuex + 開源js繪圖庫,打造一個屬於自己的在線繪圖軟件,最終效果:http://topology.le5le.com 。如果你覺得好,歡迎給文章和開源庫點贊,讓我們更有動力去做好!

本系列教程源碼地址:Github

一、利用vuex進行消息通信,發送菜單命令

vue消息通信的方式很多,我們這裏只講vuex的方式。

1. 新建一個文件store/event.js

export const state = () => ({
  event: {
    name: '',
    data: null
  }
})

export const mutations = {
  // 更新state的函數一
    // 參數:state,上面的state
    // 參數:event,新的數據
  emit(state, event) {
    state.event = event
  }
}複製代碼

這裏,我們只用關注state和mutations即可,Nuxt.js會自動補全完整的vuex。store文件下的文件名event會自動轉換爲vuex的module:event。

其中,state是我們的全局數據保存狀態;mutations是沒有異步的更新數據的方法集合;actions是異步更新數據的方法集合(這裏暫時沒有)。

2. 在頂部導航菜單事件裏,更新數據

layouts/default.vue的菜單響應事件:

 methods: {
    onMenu(key, keyPath) {
      if (!key || key.indexOf('/') === 0) {
        return
      }

      switch (key) {
        case 'about':
        case 'about2':
          this.about = true
          break
        case 'license':
          this.license = true
          break
        case 'joinin':
          this.joinin = true
          break
        default:
          this.$store.commit('event/emit', {
            name: key
          })
          break
      }
    }
  }複製代碼

其中,通過this.$store.commit去發送無異步狀態的更新store數據請求。'event/emit' 中的event指store的module:event(.js);emit指mutations或actions中的函數名。因爲這裏是通過commit方式去更新數據,所以對應的是mutations中的emit函數。commit的第二個參數,是我們要更新的最新數據。

3.在pages/index.vue監聽消息事件

當我們更新store數據後,各個頁面數據會自動更新。我們這裏通過watch的方式去監聽消息:

computed: {
    event() {
      return this.$store.state.event.event
    }
  },
  watch: {
    event(curVal) {
      if (this['handle_' + curVal.name]) {
        this['handle_' + curVal.name](curVal.data)
      }
    }
  }複製代碼

首先,我們通過動態的屬性計算computed來設置一個動態屬性event,然後通過watch監聽event的變化,即完成了消息監聽。

不同的菜單事件對應的畫布操作,參考畫布的API文檔

二、利用vuex,實現右上角狀態欄

1. 新建一個文件store/canvas.js,保存全局畫布狀態

export const state = () => ({
  data: {
    scale: 1,
    lineName: 'curve',
    fromArrowType: '',
    toArrowType: 'triangleSolid',
    locked: 0
  }
})

export const mutations = {
  data(state, data) {
    state.data = data
  }
}複製代碼

 

2. 在onMessage(畫布消息返回函數)監聽狀態變化,更新數據

onMessage(event, data) {
      switch (event) {
        case 'node':
        case 'addNode':
          this.props = {
            node: data,
            line: null,
            multi: false
          }
          break
        case 'line':
        case 'addLine':
          this.props = {
            node: null,
            line: data,
            multi: false
          }
          break
        case 'multi':
          this.props = {
            node: null,
            line: null,
            multi: true
          }
          break
        case 'space':
          this.props = {
            node: null,
            line: null,
            multi: false
          }
          break
        case 'moveOut':
          break
        case 'moveNodes':
        case 'resizeNodes':
          if (data.length > 1) {
            this.props = {
              node: null,
              line: null,
              multi: true
            }
          } else {
            this.props = {
              node: data[0],
              line: null,
              multi: false
            }
          }
          break
        case 'resize':
        case 'scale':
        case 'locked':
          if (this.canvas && this.canvas.data) {
            this.$store.commit('canvas/data', {
              scale: this.canvas.data.scale || 1,
              lineName: this.canvas.data.lineName,
              fromArrowType: this.canvas.data.fromArrowType,
              toArrowType: this.canvas.data.toArrowType,
              fromArrowlockedType: this.canvas.data.locked
            })
          }
          break
      }
    }複製代碼

canvas.data數據很多,這裏我們只關注幾個全局狀態屬性。也是因爲vuex的原因,不能直接傳入原始json對象this.$store.commit('canvas/data', this.canvas.data),會報錯。

3. 在layouts/default.vue狀態欄顯示數據

[這裏只實現了部分]我們通過computed動態屬性來暴露給ui顯示:

computed: {
    scale() {
      return Math.floor(this.$store.state.canvas.data.scale * 100)
    },
    lineName() {
      const lineNames = {
        curve: '曲線',
        polyline: '折線',
        line: '直線'
      }
      return lineNames[this.$store.state.canvas.data.lineName]
    }
  }複製代碼

 

4. 右上角狀態欄下拉選項,通過前面消息事件通信,修改畫布狀態

file如圖,通過相同的菜單消息更新畫布狀態。

 

三、其他

至此,頂部導航菜單和簡單的狀態欄就完成了,後續功能完善待續。

但,但,但...完整狀態欄還沒完成,希望大家根據開發文檔去參與完善,展示自己舞臺的機會到了,可加入貢獻者名單哦!不清楚的,歡迎聯繫管理員:(微信)alsmile123,或加羣:

topology技術討論羣2

如何貢獻

通過GitHub的pr方式:

  1. 閱讀開發文檔,瞭解相關屬性。
  2. fork倉庫到自己名下
  3. 本地修改並提交到自己的git倉庫
  4. 在自己的fork倉庫找到 “Pull request” 按鈕,提交
    file

開源項目不易,歡迎大家一起參與,給【文章、GitHub開源庫】點星點贊,或資助服務器:
file

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