專案背景:
g買賣h5是執行在多端的遊戲交易平台。基於產品層面的功能公升級以及提高開發效率的需求,前段時間我用vue和webpack對專案進行了一次漸進式的重構。所謂漸進式,即每個週期僅對部分頁面進行改造,不影響其他業務的開展。這次我改造的是我買到的/我賣出的訂單列表以及訂單詳情。
此次分享主要有以下幾個點:
核心技術
實現元件化
資料管理
**層面改善點
遇到的坑
持續優化點
核心技術
這次重構用到的核心技術是vue2.0和webpack1.0。接下來對它們進行簡要的介紹。
vue.js是一套構建使用者介面的漸進式框架。 與其他重量級框架不同的是,vue 採用自底向上增量開發的設計。 vue 的核心庫只關注檢視層,並且非常容易學習。具體可以從官網學習它的用法。
webpack是當下最熱門的前端資源模組化管理和打包工具,它可以將很多鬆散的模組按照依賴和規則打包成符合生產環境部署的前端資源,還可以將按需載入的模組進行**分割,等到實際需要的時候再非同步載入。
下圖是官方對webpack的簡介,通過這幅圖看出,相互依賴的模組檔案,會被打包成乙個或多個js檔案,可以減少http的請求次數。
webpack的具體用法可以參照
官網。此次重構用到的vue版本是2.1.0,webpack是1.13.2。
目錄結構:
gmmh5
|-- build //構建目錄
| |-- build.js
| |-- dev-client.js
| |-- dev-server.js
| |-- hashedmoduleidsplugin.js
| |-- utils.js
| |-- webpack.base.conf.js
| |-- webpack.dev.conf.js
| |-- webpack.prod.conf.js
|-- config //配置檔案
|-- dist //打包後的檔案
|-- src //原始碼目錄
| |--assets // 靜態資源
| |--biz // 頁面配置檔案
| |--common // 公共方法
| |--components // 基礎元件
| |--constants
| |--modules // 業務元件
| |--pages // 頁面
| |--utils // 工具函式
複製**
如何實現元件化?
元件化的好處不一一枚舉了,職責單一,易維護,可擴充套件...
首先我將這兩張頁面分別按功能和展現劃分了元件。
如下圖的訂單列表頁面,頁面從上到下按照功能可以劃分為三個元件:選擇商品型別,切換交易狀態,以及渲染列表資料的元件
訂單詳情也是同樣的處理方法。
關於元件間的通訊,父元件的資料通過prop下發到子元件中,子元件通過vue的$on, $emit 事件介面來與父元件通訊。兄弟元件或者層級比較深的元件,在目前沒有採用vuex的情況下,使用eventbus進行通訊。具體操作方法如下:
首先命名乙個event-bus.js,建立乙個新的全域性vue例項,命名為eventbus並且匯出該物件。
import vue from 'vue'
var eventbus = new vue()
export default eventbus
複製**
在元件a中同時引入vue和eventbus。當這個元件中的方法「emitmethod」被呼叫時,它觸發了事件」event_name」,並且傳遞了「payload」引數。
import vue from 'vue';
import eventbus from 'event-bus'
vue.component('component-a',
}});
複製**
在另外乙個元件b中,我們可以註冊乙個監聽事件,來監聽由eventbus傳遞來的事件「event_name」。
import vue from 'vue';
import eventbus from './event-bus';
vue.component(『component-b』, );
}});
複製**
這樣b元件就可以監聽a元件觸發的事件,而不需要考慮過多的層級問題。
資料管理
處理訂單詳情複雜的部分在於它的頁面展示取決於商品型別與交易狀態值。
g買賣h5頁面有以下幾種商品型別,其中賬號還分為手遊,端遊,外部寄售賬號。點券也包含撮合點券,普通點券的型別。實際處理的商品型別比下圖複雜。
每個商品型別下有不同的狀態值,其中賬號的狀態值最多。商品型別和狀態值共同決定了頁面中內容的顯示:狀態說明的標題,頂部文字說明,交易圖示以及操作項按鈕。
為了處理這類資料 ,不與頁面邏輯雜糅在一起,我將其做成了配置表。部分**如下:
const account = ,
'2': ,
...}複製**
account代表商品型別中的賬號型別。'1', '2'則是狀態值。
取值時在頁面中呼叫商品詳情的介面,獲取到資料detail,取出detail中的goods_type和state_to_out,即商品型別和商品交易狀態值。然後在配置config檔案檔案中取得對應的資料。譬如,取狀態說明的標題title:
const vm = this
let goods_type = vm.detail.goods_type
let state_to_out = vm.detail.state_to_out
title = vm.config[goods_type][state_to_out]["title"]
複製**
這樣的好處是一目了然,要進行任何的改動在配置表裡改動即可。
**層面改善點
減少重複的**
原先的**,存在的情況是:乙份**在多個地方複製,改動時經常不知道**改了**漏了。我將許多重複的**梳理一遍,抽象封裝重複的**邏輯。
譬如操作按鈕中的很多函式,呼叫了ajax之後都會重新整理頁面,於是我將其抽出來單獨寫成乙個函式:
operaterefresh(url, params) else
})}複製**
單一職責原則編寫方法
單一職責就是乙個物件(方法)只做一件事。 如果乙個方法承擔了過多職責,那麼乙個職責發生變化可能會影響其他職責的實現,修改**就變得比較危險。
此次改造我將一些大的函式按功能細分成一些小的功能函式。譬如列表頁在初始時要做的事情包括:判斷買單還是賣單,獲取初始化的商品型別,調取介面獲取列表資料以及監聽其他元件的事件:
created
() 複製**
遇到的坑
重構過程中遇到的坑更多是由於對業務的不夠充分理解上,這回用vue2.0來重構也遇到了一些vue的坑。
由於 vue 會在初始化例項時對屬性執行 getter/setter 轉化過程,所以屬性必須在 data 物件上存在才能讓 vue 轉換它,才能檢測到它的變化。vue是不能檢測到屬性的新增或刪除的。在部分業務中我對資料屬性進行新增,以及修改,卻沒有引發vue的重新渲染,在這個點上卡住了一些時間。後來閱讀了官方文件,發現它可以使用 vue.set(object, key, value) 方法將響應屬性新增到巢狀的物件上,從而觸發元件的更新:
vue.set(vm.someobject, 'b', 2)
複製**
另外,由於vue 非同步執行 dom 更新。只要觀察到資料變化,vue 將開啟乙個佇列,並緩衝在同一事件迴圈中發生的所有資料改變。如果同乙個 watcher 被多次觸發,只會一次推入到佇列中。如果想要在資料變化之後立即更新dom,可以在資料變化之後立即使用 vue.nexttick(callback) 。
vue.nexttick(function
() )
複製**
持續優化點
業務完成了,我還整理了一些可以持續優化的點:
效能。部分檔案體積可以近一步縮小,可以更有效地利用快取,提公升首屏渲染速度。
體驗。提公升下拉重新整理的體驗以及新增頁面互動時的提示。
資料流。整合更多業務進來時,對資料流的結構設計要更加清晰。
元件化。基礎元件可以更抽象化,利於復用。
總結經過這次的重構,我對業務有了更深入的了解和掌握,並且認識到在面對複雜的業務時,停下來思考清楚業務場景比動手寫**重要得多。
0 重構概述
這一系列的重構知識總結自馬丁福勒的 重構 改善既有 的設計 一書。為什麼要重構?因為乙個專案往往不只乙個人在寫,其他人也會來讀寫你的 有些人甚至自己寫的 幾個月之後就看不懂當初自己寫的是什麼了。重構的目的 改進軟體的設計,使軟體更易理解,容易找出bug,在後期要新增新功能時,提高程式設計速度,重構後...
vue2 0學習記錄
1 在main.js可註冊全域性元件,vue.components 元件名稱 元件名 import 元件名 from components 元件檔案 3 元件的標籤名不可與系統的html標籤重複 4 父元件向子元件傳值 父元件有乙個陣列 users 在父元件模板中的子元件標籤中接收 users us...
Vue2 0使用小結
近期第一次使用vue快速開發了一款前端專案,開發效率與便捷性大幅提公升,體驗了一把vue的藝術之道,在此總結下目前所接觸到的vue基礎使用知識,後續會補充遇到的知識點和問題以及解決方案.簡介 vue 是典型mvvm框架,擁有雙向繫結的能力與完整的元件化方案,利用 virtual dom 提供了函式式...