使用過一些清單類的應用程序,像 WunderList, Google Keep等,用來記錄一些計劃和安排,也試着將本身的計劃安排同筆記一塊兒整理在 Evernote 中,可是不管哪一種方式用起來總以爲少了點什麼,若是二者的一些功能可以結合起來,就很完美了。html
「todo」和「note」之間的關係原本就很微妙,一個「todo」寫得詳細點不就成了「note」嗎?因而本身寫了一個稍微複雜一點的清單程序,今天將項目總結整理在此。前端
我試着將 todo和 note 結合,能夠像 WunderList 同樣記錄計劃,又能夠 Evernote 同樣管理筆記。在開發過程當中,反覆調整和修改,最終發現:其實我只是作了一個支持 markdown 的 簡易版WunderList :(。無論怎麼樣,能堅持下來就是值得鼓勵的。整個工程先後端分離,後端實現不在此介紹git
接下來,我簡單介紹一下 simplelist 的前端實現過程。注意,下面介紹的一些過程不是一蹴而就,是反覆修改和整理得出的,好比技術選擇和組件的劃分。docker
有三點後端
肯定須要實現的功能數組
肯定界面markdown
肯定技術實現的方案架構
功能和界面先放一邊,介紹一下采用的技術方案。其實也沒啥可介紹的,前端老司機花樣多,可是主流的套路也就那麼幾種,我選擇「套路のVue」。Vue+ Vuex+ Vue-Router,其餘配件像 Less,Webpack等你們也應該都清楚。用戶登錄註冊及接口的實現不在本文章的討論中,下次再講。mvc
在 React 的組件化的劃分方式中,將組件分紅兩種:Container Components和Presentational Components,容器組件和 UI組件。容器組件負責數據和業務邏輯的處理,攜帶相關的內部狀態,與數據有頻繁的交互, UI組件只負責 UI 的呈現,沒有任何的數據和邏輯的處理,組件的數據從容器組件傳遞進來(在 React中數據由 this.props 提供)。若是一個組件既有 UI 又有業務邏輯,能夠試着將它拆分紅兩個:一個容器組件,包着一個UI 組件。前者負責與外部的通訊,將數據傳給後者,由後者渲染出視圖。
我的比較喜歡這種方式,組件變得純粹。不過彷佛在 Vue 生態圈中沒有設計這方面的介紹,在後面我打算嘗試使用這種方式,不過如今仍是使用相對粗暴一點的方式來劃分。
這是 WunderList 的界面,簡單的分析以後,能夠將其劃分紅以下形式,再詳細一點的話能夠看下圖,若是堅持容器組件和 UI組件的形式開發的話,相對較複雜一點,而我選擇先從簡單的入手。想必你應該看過TodoMVC,而這樣也是simplelist 的最簡單也是最核心的功能。因此在實際操做過程當中,我先將輸入框和單個任務這兩個組件實現。
Vuex 是一個專門爲 Vue.js 應用所設計的集中式狀態管理架構。它借鑑了 Flux 和 Redux 的設計思想,但簡化了概念,而且採用了一種爲能更好發揮 Vue.js 數據響應機制而專門設計的實現。
在單獨使用 Vue.js 的時候,一般會把狀態儲存在組件的內部。整個應用的數據和狀態都是散落在各個組件。這樣並無有什麼問題,組件的數據組建本身管理。有時候狀態的一部分須要共享給其餘的組件,此時使用事件系統,讓一個組件把一些狀態「發送」到其餘組件,可是當項目一步步擴大時,事件流將變得繁雜,不利於調試和維護。此時 Vuex 能夠幫助咱們實現狀態的管理。
Vuex 的四個核心概念分別是:
The state tree:Vuex 使用單一狀態樹,用一個對象就包含了所有的應用層級狀態,做爲一個『惟一數據源(SSOT)』而存在。每一個應用將僅僅包含一個 store 實例。單狀態樹讓咱們可以直接地定位任一特定的狀態片斷,在調試的過程當中也能輕易地取得整個當前應用狀態的快照。數據流都是單向的。
Getters:用來從 store 獲取 Vue 組件數據。
Mutators:事件處理器用來驅動狀態的變化,只有 mutation 能夠改變狀態。
Actions:能夠給組件使用的函數,用來派發 Mutation。
Vuex 規定,屬於應用層級的狀態只能經過 Mutation 中的方法來修改,而派發 Mutation 中的事件只能經過 action。從組件出發,組件中調用 action,在 action 這一層級咱們能夠和後臺數據交互,好比獲取初始化的數據源,或者中間數據的過濾等。而後在 action 中去派發 Mutation。Mutation 去觸發狀態的改變,狀態的改變,將觸發視圖的更新。
配合 Vuex 這樣的數據管理架構,我只須要關心組件的狀態變化,數據的變化和流通所有交給 Vuex。我須要維護一個數組,數組中每個元素表明一個任務,輸入框和任務上的編輯刪除等操做,本質上都是對一個數組的操做。
我已經說過了,我要作的是複雜的 simplelist。因此,在完成了最簡單的增刪改的功能以後,要加上任務的本身的歸屬了。每一個任務都歸屬於一個清單,有惟一的清單 id(list_id)。就像 WunderList 同樣,左側清單列表,右側任務列表。這時候須要用到單頁引用中必不可少的路由裝置了。
從簡單的開始,除了登陸和註冊(目前整合在應用中,更好的作法應該是登陸註冊做爲兩個單獨的頁面,這裏只是我的 demo,暫不考慮),暫且只有一種路由狀態,用來指向對應的清單,例如:/lists/:id
。下面是僞代碼
<div id="app"> <router-view></router-view> </div>
const ListItem = { template: `<div class="item">{{item.title}}</div>`, props: ['item'], } const ListContainer = { template: `<div class="list"> <h2>List {{ $route.params.id }}</h2> <div class="item-list"> <list-item v-for="item in list" :item='item'></list-item> </div> </div>`, components: { 'list-item': ListItem, }, } const router = new VueRouter({ routes: [ { path: '/lists/:id', component: ListContainer } ] })
而後綁定好 <router-link>
,路由切換就算完成了。可是光這樣還不行,最關鍵的清單數據管理尚未加上。其實清單的數據狀態管理與任務的管理大同小異,就不在此複述,你能夠試着捋一捋。
在建立和編輯清單的時候,須要彈出一個 modal 來方便操做(參照 WunderList)。這個時候就涉及到一個問題:這種定位不是很清晰的模塊,該怎麼來管理?
在我看來,這種類型模塊大體有兩類,一類是全局共享,可能在不少不一樣的組件中都須要調用,這種全局的我認爲能夠單獨拿出來放在同一個地方供應用調用。另外一類是隻屬於某一個組件,只會在固定的組件中被調用,這類模塊推薦直接寫在組件中,方便管理,最好是寫在頂級組件中,避免一些全七八糟的樣式衝突(目前我遇到的主要仍是層疊順序的問題)。
思路清晰以後,能夠很順利的完成清單的建立和編輯功能。
說到這,一個複雜的 simplelist 的基本結構和功能已經出現了。那麼問題來了,你學到了嗎?