[VueJS] 工具開發心得

首先可以先看一下 Kuro 的投影片,先瞭解一下 VueJS 的基本運作方式,然後就可以收工了(喂


先求不傷身體

VueJS Simple Gantt

專案 Github 在這裡,

https://github.com/hinablue/vuejs-gantt

這是隨意寫的工具,程式碼很亂請當作沒看到,謝謝。

再來講究效果

首先你可以參考任何一個 VueJS 的範例,利用他們的結構來建置你所想要的環境。或者你也可以使用 vue-cli 來安裝,也是挺方便的。

$ vue init webpack my-project

這樣就可以建立好一個基本的專案以供使用了。

首先這個工具有用到幾個東西,先羅列出來:

安裝方式就用 npm 裝一裝,再 import 進來就可以使用了。

製 (ㄘㄞˇ) 作 (ㄌㄟˊ) 過程心得

先講講 Vuex 這個東西。

Vuex

Vuex 算是相當容易理解的工具,跟 React 的 Flux 基本上概念是相同的。用他來處理或是傳遞一些資料相當方便。而且資料在元件之間傳遞也有不少好處,

  • 減少事件(Events)使用
  • 降低監看的($watch)開銷
  • 保持元件之間資料的一致性
  • 更容易的溝通(因為只透過 getters, actions 來傳遞,只要把需要的方法引入就好了

https://github.com/hinablue/vuejs-gantt/blob/master/src/vuex/store.js

當然,他畢竟是存放資料的地方,遇到需要監聽或是觸發狀態的時候,該要用到的監聽或是觸發事件,或是監看($watch)還是不能少,

  1. 可以用 actions 設定資料,然後監看 getters,來取代事件(算是怪招,但是有效,因為 2.0 之後會將 $broadcast$dispatch 拿掉,所以這招可以取代
  2. 元件內的事情還是用 $on, $emit 做掉就好
  3. 因為無法得知 同層元件 被渲染出來的先後順序,所以可能 A1 元件設定了一個儲存值,A2 元件即便到最後(attached)都無法得知
  4. 第 3 點可以用第 1 點作弊得知,請看以下的例子,

    https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttMainContainerRows.vue#L61
Recursive Component

有個很重要的事情,

千萬不要在這種元件中找老爸
千萬不要在這種元件中找老爸
千萬不要在這種元件中找老爸

除了老爸找做人可能會讓你的程式碼爆炸以外,這裡面找的老爸也不一定準確。雖然元件可以這樣被複用,但是這裡的老爸 $parent 很吃你的元件結構的設計,所以除非必要,否則請不要這樣做。

然後,this.$el.$parent 也一樣,既然都已經交給元件處理了,就不要花心思再去掃 DOM 了,對自己操作即可,不要再去操作別人(同樣的,這也很吃 <template> 當中,你的 DOM 的設計,如果結構改變,你的 this.$el.$parent 很可能就會換人。

先把資料處理完,再給元件做渲染,不要邊渲染邊做。

https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttSideTableTree.vue#L48

不要亂用 .sync

畫面初始化的時候,結構者可能會設想資料的改變。但是資料的東西你可以交給 Vuex 去處理就好,如果是關於 畫面 要呈現的事情,還是用單向綁定就可以了。範例可參考,

https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttMain.vue#L34

這裡綁了 yearMonth, yearWeeks, yearDays 並傳遞去給 ganttMainHeader 元件使用,如果資料改變,重畫就好了(爛招,當然還是有比重畫更好的作法就是。

多用 methods 處理雜事

雖然可能會污染 this,但是有時候就是要污染一下才方便(欸

https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttMainContainerTasks.vue#L36

元件的 attached 只是把東西畫上去

我曾經試著利用 attached () 去拿 this.$el.offserHeight 然後給我 1 的結果。最後用 $nextTick 解決。

但是他有時候又會是好的(無言

https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttMainHeader.vue#L51

理論上 attached () 確實是把元件渲染到瀏覽器的畫面上了,但,他是不是真的是 渲染結束後 的觸發?這個我還是持保留的態度。

某些地方 data 用 Object 會中邪

這是我試著要隱藏畫面上的 Task 的時候遇到的問題,當我單純拿 this.data 當中的 task 資料,更改 task.display 的時候,發現畫面不會更新。

就算使用 $nextTick 也一樣。

最後,用 Object.assign 去給一個新的 Task 就沒事了。

https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttMainContainerTasks.vue#L48

這應該是被 JavaScript 的 語言特性 給婊到了。

小結

整體來說,開發上比 ng 要輕鬆一點,而且由於可以都用 ES2015 來寫,所以寫起來也比較神清氣爽。當然,這工具只是研究用亂寫的,很多寫不好的地方就當作沒看到吧(哈哈

總結來說,設計工具在 VueJS 上面挺方便的,

Hina Chen

偏執與強迫症的患者,算不上是無可救藥,只是我已經遇上我的良醫了。