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

專案 Github 在這裡,
這是隨意寫的工具,程式碼很亂請當作沒看到,謝謝。
再來講究效果
首先你可以參考任何一個 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)還是不能少,
- 可以用
actions設定資料,然後監看getters,來取代事件(算是怪招,但是有效,因為 2.0 之後會將$broadcast與$dispatch拿掉,所以這招可以取代 - 元件內的事情還是用
$on,$emit做掉就好 - 因為無法得知 同層元件 被渲染出來的先後順序,所以可能 A1 元件設定了一個儲存值,A2 元件即便到最後(
attached)都無法得知 - 第 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 上面挺方便的,
- 能拆元件就拆元件
- 資料溝通交給專業的去做(Vuex
- 畫面渲染的東西先處理過再去做渲染
- 盡量少做 找老爸 這件事,不管是元件還是 DOM
- 如果可以,找替代方案或是工具,會比自己做來得愉快些
但是我還是自己做了拖曳的元件(被揍
https://github.com/hinablue/vuejs-gantt/blob/master/src/components/ganttSideResizer.vue