關鍵詞 裝飾器
Decorator
元編程
html
裝飾器是一種特殊類型的聲明,它可以被附加到類聲明,方法, 訪問符,屬性或參數上。 裝飾器使用 @expression這種形式,expression求值後必須爲一個函數,它會在運行時被調用,被裝飾的聲明信息作爲參數傳入。vue
本篇先從項目的宏觀角度來總結一下Decorator如何組織。ios
我會持續分享一些知識整理,若是文章對您有幫助記得點贊鼓勵一下哦😁~,也能夠經過郵件方式聯繫我文章列表: https://juejin.im/user/5bc8b9... git
郵箱地址: 595506910@qq.comgithub
主要的Decorator依賴vuex
vue-cli3 默認支持Decorator, 年初重寫了一個design庫主要依賴官方和社區提供的Decorator來實現的組件。
Decorator能夠非侵入的裝飾類、方法、屬性,解耦業務邏輯和輔助功能邏輯。如下是主要的三方Decorator組件,有了這些組件經常使用的Vue特性就能夠所有轉成Decorator風格了。vue-cli
get computedMsg () {return 'computed ' + this.msg}
mounted () {this.greet()}
讓Vuex和Vue之間的綁定更清晰和可拓展express
這個組件徹底依賴於vue-class-component.它具有如下幾個屬性:npm
建議項目中只引用vue-property-decorator就能夠了,避免@Component從vue-class-component和vue-property-decorator兩個中隨意引用。
總結一下主要就分紅這三類:編程
以上引用方法等詳系內容可查看官方文檔。要想完整的發揮Decorator的價值就須要根據須要自定義一些裝飾器。下面自定義部分就來實現一個記錄日誌功能的裝飾器。
指望的日誌格式
{ "logId":"", // 事件Id "input":"", // 方法輸入的內容 "output":"", // 方法輸出的內容 "custom":"" // 自定義的日誌內容 }
實現
export function Logger(logId?: string, hander?: Function) { const loggerInfo =Object.seal({logId:logId, input:'',output:'', custom: ''}); const channelName = '__logger'; const msgChannel = postal.channel(channelName); msgChannel.subscribe(logId, logData => { // 根據業務邏輯來處理日誌 console.log(logData); }); return function (target: any, key: string, descriptor: TypedPropertyDescriptor<any>): TypedPropertyDescriptor<any> { const oldValue = descriptor.value descriptor.value = function () { const args: Array<any> = []; for (let index in arguments) { args.push(arguments[index]); } loggerInfo.input = `${key}(${args.join(',')})`; // 執行原方法 const value = oldValue.apply(this, arguments); loggerInfo.output = value; hander && (loggerInfo.custom = hander(loggerInfo.input, loggerInfo.output) || ''); // 被調用時,會自動發出一個事件 msgChannel.publish(logId, loggerInfo); } return descriptor } }
使用
// 直接使用很是簡潔 @Logger('event_get_detial1') getDetial(id?: string, category?: string) { return "詳細內容"; } // 或者使用自定義,讓日誌和業務邏輯分離 @Logger('event_get_detial2', (input, output) => { return '我是自定義內容'; }) getDetial2(id?: string, category?: string) { return "詳細內容"; } ... <button @click="getDetial2('1000', 'a')">獲取詳情</button>
效果: {logId: "event_get_detial2", input: "getDetial2(1000,a)", output: "詳細內容", custom: "我是自定義內容"}
, 每次點擊按鈕都會觸發一次。
TODO: 這裏還須要對輸入參數和輸出參數中的引用數據類型作處理。
同時還須要掌握:裝飾器工廠、裝飾器組合、裝飾器求值、參數裝飾器、元數據
舉個例子 join(separator?: string): string;