使用 js 修飾器封裝 axios

weixin_33766168發表於2018-12-20

修飾器

修飾器是一個 JavaScript 函式(建議是純函式),它用於修改類屬性/方法或類本身。修飾器提案正處於第二階段,我們可以使用 babel-plugin-transform-decorators-legacy 這個 Babel 外掛來轉換它。

類修飾器


@Dec
class Topic{

}

function Dec(target){
    target.type = 'Topic';  // 類的靜態屬性
    target.prototype.type = 'topic object'; //類的例項屬性
}

var topic = new Topic();
console.log(Topic.type); // Topic
console.log(topic.type); // topic object

修飾器是一個對類進行處理的函式。類修飾器函式的第一個引數,就是所要修飾的目標類。
函式Dec的引數target,就是被修飾的類。如果要在類的例項上新增屬性可通過 target.prototype。
如果要通過修飾器傳遞引數可在修飾器外面封裝一層(多層)函式。


function Decs(type){
    return target => {
        target.type = 'Topic' + type;
        target.prototype.type = 'topic ' + type;
    }
}

注意: 修飾器對類的行為的改變,是程式碼編譯時發生的,而不是在執行時。這意味著,修飾器能在編譯階段執行程式碼。也就是說,修飾器本質就是編譯時執行的函式

看一個例子,通過類修飾器給 React 元件新增 axios 例項:


//App.js
@Create({
    baseURL: 'https:xxx.xxx.xxx',
})
class App extends Component{
    constructor(props) {
        super(props);
    }

    componentWillMount() {
        this.$axios.get('/user?ID=12345');
    }
}

// Create修飾器
const Create = config => (target, property, descriptor) => {
    // 避免在類的方法上使用
    if (!descriptor) { 
        target.prototype.$axios = axios.create(config);
    }
}

類方法修飾器


class App extends Component{
    constructor(props) {
        super(props);
    }

    @GET('/user?ID=12345')
    getUser(res) {
        // 
    }
}

// axios get請求簡單封裝
function GET(url){
    return function(target, name, descriptor) {
        let oldVal = descriptor.value;

        // descriptor.value為當前修飾器所修飾的屬性值
        descriptor.value = function(){
            axios.get(url)
                .then((res)=>{
                    oldVal.apply(this, res.data);
                }).catch((err)=>{
                    oldVal.apply(this, {}, err)
                });
        }
    }
}

類方法的修飾器函式一共可以接受三個引數,第一個引數是類的原型物件,上例是App.prototype,修飾器的本意是要“修飾”類的例項,但是這個時候例項還沒生成,所以只能去修飾原型(這不同於類的修飾,那種情況時target引數指的是類本身);第二個引數是所要修飾的屬性名,第三個引數是該屬性的描述物件。

最後

基於decorator(修飾器)的方便,封裝了一個 axios 的網路請求庫,歡迎大家來star retrofit-cjs

來源:https://segmentfault.com/a/1190000016036391

相關文章