首先可以先看一下 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