摘要:如何管理項目的數據這個問題似乎早已經有答案了,無非就是使用,全局,整個應用維護一個超大的,界面的顯示情況隨著超大的變化而變化。
vuex
如何管理 vue 項目的數據?這個問題似乎早已經有答案了,無非就是使用 vuex ,全局 store,整個應用維護一個超大的 Object,界面的顯示情況隨著超大 Object 的變化而變化。
看起來很簡單,不就維護一個 Object 嘛,實際上,要想組織好數據這塊代碼,必須事先對項目的數據結構理解得非常透徹,然后像設計數據庫表一樣把各個 module 的樣子設計出來。實際上,個人覺得設計 vuex 的 module 比設計數據庫表復雜得多:
1、像數據庫一樣設計各個業務實體的外貌,這部分設計難度應該和數據庫表設計差不多;
2、維護一堆 ajax 請求狀態;
3、如何優雅地復用 module。比如有一個 PersonListModule,在一個頁面上有兩處要用到 PersonListModule 中的列表數據:一個是要在表格控件里面展示,一個是要在下拉控件里面展示,每個控件中展示的列表數據篩選條件不一樣;
4、如何同步 vuex 中的數據和服務器端數據。vuex 的超大 Object 可以看做服務器端數據在客戶端內存中的一個緩存,怎么設計這個緩存的同步策略?
對于3、4兩個問題,結合起來更恐怖:同步服務器端數據到 PersonListModule 的同時,還要考慮如何從 PersonListModule 中篩選出分頁數據到頁面展示,還要篩選出多個列表,還要考慮在什么時機重新更新“緩存”,想想就頭大。
假設我們能力很強大,設計出了能完美應對上述問題的 store 方案,還有一個大問題攔著我們呢:如何保證這套設計的可擴展性?因為業務系統變化多端,不知道什么時候產品經理又有新想法了,我們得設計能很好地應對變化多端的需求嗎?
為什么這么難?問題究竟出現在哪里?vuex 的思維模式主要是從數據著手,由數據推導出界面的樣子,這就需要先設計好 store 結構了。要設計好 store 結構,目測必須具備如下特質的工程師才能做好:
1、對項目業務了解非常深入;
2、具備超強的抽象思維能力;
3、經驗豐富,能盡量想到設計出的 store 結構能應付哪些情況、不能應付哪些情況。
第2條的門檻實在是太高了,能做到的前端工程師估計沒多少。
怎么辦?我們不應該從數據推導出界面,而應該從界面推導出數據,逐層抽象。
比如現在要仿一個新浪微博首頁,頁面上主要包含的數據有:分組信息、微博列表、個人信息、一些推薦信息等,那么就設計一個只針對該頁面的 module ,大致結構為:
const homePageModule = { state: { groupList: [{ id: 1, name: "名人明星", unread: 1 }, { id: 2, name: "同事", unread: 0 } ], groupListExtraInfo: { // 初始顯示多少個小組 initShowCount: 5, loading: true }, weiboList: [{ id: 1, content: "震驚部
", author: "yibuyisheng", createTime: "20170719234422" }], weiboListPageInfo: { loadingStatus: "QUIET", // 三種取值:QUIET -> 沒有加載;UP -> 向上加載;DOWN -> 向下加載 // weiboList 的開始時間,可用這個時間戳做下一次的向上加載 startTime: "20170719234422", // weiboList 的結束時間,可用這個時間戳做下一次的向下加載 endTime: "20170719234422" }, self: { id: 1, nickname: "yibuyisheng", email: "yibuyisheng@163.com", avatar: "http://weibo.com/2674779523/profile?rightmod=1&wvr=6&mod=personinfo", followedCount: 405, followerCount: 235, weiboCount: 1321 }, recommendMovies: [ ... ], recommendTopics: [ ... ] ... }, mutations: { updateWeiboList(state, list) { ... } }, actions: { appendWeiboList() { ... }, prependWeiboList() { ... } } };
針對這個頁面,這個結構,各個處理邏輯就具體化、特殊化了,代碼寫起來非常輕松。
代碼復用?假設現在有個小組頁面,點進去后可以看到該小組所有成員發的微博,因為是一個新的頁面,所以需要新起一個 module ,這也意味著要重復寫一遍 weiboList 相關的代碼,豈不蛋疼!
此時可以考慮寫一個 createWeiboListModule() 函數,用于創建這種通用 module ,然后再寫一個 mergeModules() 函數,把 createWeiboListModule() 函數創建出來的 module 對象和各頁面特殊的 module 合并起來,樣子看起來大致是這樣:
mergeModules(createWeiboListModule(), { state: { ... }, mutations: { ... }, actions: { ... } });
遇到需要復用的才抽取通用邏輯,很自然,很簡單。
怎么結合 vue 組件?上面的結構有一個很大的問題,就是不能很好地和 vue 組件結合。比如,要讓微博首頁和分組頁面中的微博列表能復用 weiboList 相關代碼,那么 weiboList 涉及到的 state、action、mutation、getter 的命名都要盡量保持一致,不然就要傳一個 nameMap(命名映射)給兩個頁面通用的 WeiboListComponent 組件,看起來就像這樣:
簡直蛋疼!
好吧,那就嚴格約束這兩個頁面的 state、action、mutation、getter 命名都保持一致吧!
簡直超級蛋疼!
此時可以考慮用 namespace 來解決這個問題,比如上面的 homePageModule 可以把 weiboList 拆分出來:
const store = new vuex.Store({ ..., modules: { "page:home": { state: { groupList: [{ id: 1, name: "名人明星", unread: 1 }, { id: 2, name: "同事", unread: 0 } ], groupListExtraInfo: { // 初始顯示多少個小組 initShowCount: 5, loading: true }, self: { id: 1, nickname: "yibuyisheng", email: "yibuyisheng@163.com", avatar: "http://weibo.com/2674779523/profile?rightmod=1&wvr=6&mod=personinfo", followedCount: 405, followerCount: 235, weiboCount: 1321 }, recommendMovies: [ ... ], recommendTopics: [ ... ] ... }, }, "page:home:weiboList": createWeiboListModule(...) } ... });
這樣一來,只要給 vue 組件傳一個 namespace 參數就行了:
嗯,看起來挺好的!
如何處理“store 緩存”?可以在上一個問題解決的基礎上,加上緩存功能,目測有大把現成的緩存策略可以參考(服務器端都玩兒爛了),由于絕大部分系統并不需要這層緩存功能,所以此處不贅述。
就這樣了嗎?上述方案,思維方向的確是導致最后執行起來輕松了很多,從具體到抽象的過程,很自然,符合思考習慣。但是最終的代碼還是會很容易搞得很亂的:
1、mergeModules() 要照顧各種合并策略;
2、createXXXModule() 方法會抽出很多層。比如可以從 createWeiboListModule() 抽出來 createContinuousListModule() ,用于構造通用的具備“向前向后”加載能力的列表 Module,最終可能會形成一條常常的“繼承鏈”,需要自己去定義維護這套繼承邏輯,心累。
其實上面兩條一看,就知道有現成的解決方案了: class。
參考此處實現:https://github.com/yibuyishen...(代碼還在完善中)。
具體業務代碼寫起來就像是這樣了:
class ContinuousList extends BaseModule { state = { list: [], pageInfo: { loadingStatus: "QUIET", startTime: "20170720003939", endTime: "20170720003939" } } @action async appendList(...) { ... const result = await request("some url", params); this.updateList(result.list); ... } @action prependList(...) { ... } } class WeiboList extends ContinuousList { @action async voteUp(...) { ... await request("some url", params); const weiboDetail = await updateWeibo("some url", params.weiboId); const newList = this.state.list.map((wb) => { return wb.id === weiboDetail.id ? weiboDetail : wb; }); this.updateList(newList); ... } } @composition(WeiboList) class HomePage extends BaseModule { $namespace = "page:home:"; ... @action requestRecommendInfo(...) { ... } ... } HomePage.register();
在對應的 HomePage.vue 里面,大致是這樣:
......
而 WeiboListComponent 組件大致是這樣:
總結...
其實就是換一種思路:從界面推導數據,從具體到抽象。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/84149.html
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請點擊集前端最近很火的框架資源定時更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥雀呼晴,侵曉窺檐語。葉上初陽乾宿雨,水面清圓,一一風荷舉。家住吳門,久作長安旅。五月漁郎相憶否。小楫輕舟,夢入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請::點擊::集web前端最近很火的vue2框架資源;定時更新,歡迎 Star 一下。 蘇...
摘要:作為目前最熱門最具前景的前端框架之一,其提供了一種幫助我們快速構建并開發前端項目的新的思維模式。的新版本,的簡稱。的包管理工具,用于同一管理我們前端項目中需要用到的包插件工具命令等,便于開發和維護。 Vue.js作為目前最熱門最具前景的前端框架之一,其提供了一種幫助我們快速構建并開發前端項目的新的思維模式。本文旨在幫助大家認識Vue.js,了解Vue.js的開發流程,并進一步理解如何通...
摘要:哪吒別人的看法都是狗屁,你是誰只有你自己說了才算,這是爹教我的道理。哪吒去他個鳥命我命由我,不由天是魔是仙,我自己決定哪吒白白搭上一條人命,你傻不傻敖丙不傻誰和你做朋友太乙真人人是否能夠改變命運,我不曉得。我只曉得,不認命是哪吒的命。 showImg(https://segmentfault.com/img/bVbwiGL?w=900&h=378); 出處 查看github最新的Vue...
閱讀 1531·2021-09-22 15:35
閱讀 2011·2021-09-14 18:04
閱讀 883·2019-08-30 15:55
閱讀 2455·2019-08-30 15:53
閱讀 2685·2019-08-30 12:45
閱讀 1207·2019-08-29 17:01
閱讀 2583·2019-08-29 15:30
閱讀 3520·2019-08-29 15:09