欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

使用MpKit的事件、Mixin、SetData優(yōu)化、全局?jǐn)r截等功能增強(qiáng)開發(fā)多平臺(tái)小程序 ... - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識(shí)

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價(jià)值,我們?cè)谧非笃湟曈X表現(xiàn)的同時(shí),更側(cè)重于功能的便捷,營銷的便利,運(yùn)營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實(shí)提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序?yàn)楹笃谏?jí)提供便捷的支持!

您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >

使用MpKit的事件、Mixin、SetData優(yōu)化、全局?jǐn)r截等功能增強(qiáng)開發(fā)多平臺(tái)小程序 ...

發(fā)表時(shí)間:2021-1-11

發(fā)布人:葵宇科技

瀏覽次數(shù):74

前言

近年來,多個(gè)公司都開發(fā)出了小程序這樣的“微應(yīng)用”方案,其在生態(tài)擴(kuò)展、功能增強(qiáng)等方面都發(fā)揮著重要的作用;

作為開發(fā)者卻要同時(shí)面對(duì)多個(gè)小程序平臺(tái),實(shí)現(xiàn)相似的功能,如果不考慮使用框架的話,在底層的一些基礎(chǔ)技術(shù)解決方案上,有沒有一個(gè)輕量級(jí)的選擇?

我們?cè)陂_發(fā)一個(gè)小程序時(shí),往往會(huì)有以下技術(shù)需求:

  1. 全局事件總線
  2. 優(yōu)化小程序的setData函數(shù)
  3. 希望將App/Page/Component上的共有功能拆分,并可以有效性的重復(fù)利用,甚至組建為App/Page/Component基類
  4. 可以全局?jǐn)r截執(zhí)行某些操作,如:異常報(bào)錯(cuò)、網(wǎng)絡(luò)請(qǐng)求、功能制止、App/Page/Component的生命周期等

基于以上需求,都是我以往實(shí)現(xiàn)過的功能,所以我將我的經(jīng)驗(yàn)總結(jié)成了一個(gè)開源項(xiàng)目MpKit,里面就包含對(duì)以上需求的功能實(shí)現(xiàn),且不止于此;

MpKit的主要功能都經(jīng)過單元測試,可放心使用

下面我來介紹下它的具體用法和功能列表。

簡介

MpKit發(fā)布到了NPM平臺(tái),以模塊化的方式劃分為多個(gè)包,某些包不止能用在小程序平臺(tái),還可以用到h5等平臺(tái);某些包卻無法在小程序上使用,包列表及相關(guān)功能如下:

以下包均支持TypeScript語言

安裝

如果你的小程序項(xiàng)目中支持引入npm包,那么你直接根據(jù)自己的需要安裝對(duì)應(yīng)包即可,如:

npm i @mpkit/ebus -S

但是如果你是原生開發(fā),不支持引入npm包,你最大的可能需要用到 @mpkit/inject 包,此包中的功能基本包含了其他包的所有功能,且支持按需插件化安裝,可節(jié)省你的字節(jié)空間;使用 @mpkit/inject

xx/temp
npm i @mpkit/inject
  1. 找到 xx/temp/node_modules/@mpkit/inject 下的 dist 目錄,將其下內(nèi)容拷貝到你的小程序項(xiàng)目目錄下;
  2. 找到 dist/config.js 文件,將你需要的功能插件引入,如:
// 提供事件類功能
import { plugin as EbusPlugin } from './plugins/ebus';
// 提供混入功能
import { plugin as MixinPlugin } from './plugins/mixin';
// 提供setData優(yōu)化
import { plugin as SetDataPlugin } from './plugins/set-data';
var config = {
    // 是否重寫全局變量
    rewrite: {
        App: false, // 重寫全局變量App為 plugins/mixin 中的MkApp 即 MpKit.App
        Page: false, // 重寫全局變量Page為 plugins/mixin 中的MkPage 即 MpKit.Page
        Component: false, // 重寫全局變量Component為 plugins/mixin 中的MkComponent 即 MpKit.Component
        Api: false, // 重寫全局api變量wx/my/tt為 plugins/mixin 中的MkApi 即 MpKit.Api
        setData: false // 重寫Page/Component中的setData為優(yōu)化后的setData 即 MpKit.setData
    },
    plugins: [
        EbusPlugin,
        MixinPlugin,
        SetDataPlugin
    ]
};
export default config;
  1. 如果配置了 config.rewrite 項(xiàng),請(qǐng)?jiān)谛〕绦蝽?xiàng)目的 app.js 的第一行處引入 @mpkit/inject/dist 中的 index.js 文件,否則無法實(shí)現(xiàn)全局變量重寫;如果沒有配置該項(xiàng),則需要在使用時(shí)引入,如:
import MpKit from '@mpkit/inject/dist/index';
MpKit.on(...);
  1. 安裝完成。
  2. 小提示:不需要的插件js文件可以直接刪掉,插件不直接相互依賴。

使用

這里著重介紹 @mpkit/inject 包的使用方式和細(xì)節(jié),其他包可自行參考對(duì)應(yīng)文檔;

@mpkit/inject 包提供下列功能,




依賴

從上面的功能列表中可以看到,某些方法或變量是依賴插件的,如果沒有安裝相關(guān)插件,則無法使用對(duì)用方法;

App/Page/Component

當(dāng)使用 MpKit.App/Page/Component 時(shí),可傳遞多個(gè)對(duì)象,如:

import MpKit from '@mpkit/inject/dist/index';
// 如果在config中配置了rewrite.App=true,則調(diào)用App等同于調(diào)用了[未重寫的App(MpKit.App)]
App(MpKit.App({
    globalData: {
        name: 'Tom',
        age: 10
    },
    onShow() {
        console.log('onShow1')
    },
    add(a, b) {
        return a + b;
    }
}, {
    globalData: {
        age: 20
    },
    onShow() {
        console.log(`onShow2, ${this.add(2, 4)}`);
        console.log(this.globalData);
    }
}));
// 輸出:onShow1
// 輸出:onShow2, 6
// 輸出:{ name: 'Tom', age: 20 }


Component(MpKit.Component({
    data: {
        name: 'Alice',
        products: [
            {
                name: '蘋果',
                price: 6
            },
            {
                name: '香蕉',
                price: 5
            }
        ]
    },
    created() {
        console.log('created1')
    },
    methods: {
        sayhi() {
            console.log(`hi ${this.data.name}`);
        }
    }
}, {
    data: {
        products: [
            {
                price: 8
            }
        ]
    },
    created() {
        console.log('created2');
        this.sayhi();
        console.log(this.data.list);
    },
    methods: {
        sayhi() {
            console.log(`你好 ${this.data.name}`);
        }
    }
}));

// 輸出:created1
// 輸出:created2
// 輸出:hi Alice
// 輸出:你好 Alice
// 輸出:[ { name: '蘋果', price: 8 }, { name: '香蕉', price: 5 } ]

合并策略

從上面的例子可以看出合并策略是:

  • 屬性進(jìn)行深度合并
  • 方法會(huì)保留所有mixin中的方法體,按照順序全部執(zhí)行

鉤子函數(shù)

為可以進(jìn)行全局?jǐn)r截 App/Page/Component/Api 上的方法,MpKit做了鉤子函數(shù)的機(jī)制,具體為:

  • 每個(gè)方法執(zhí)行前會(huì)調(diào)用 before 鉤子
  • 如果 before 鉤子函數(shù)存在,且有返回值(如果有多個(gè) before 鉤子則取最后一個(gè)不為 undefined|true 的結(jié)果)時(shí)

    • 對(duì)于 App/Page/Component 如果返回值為 false ,則不會(huì)繼續(xù)向下執(zhí)行
    • 對(duì)于 Api 如果返回值為 false ,則不會(huì)繼續(xù)向下執(zhí)行;同時(shí)如果返回值不為 trueundefined 時(shí),會(huì)直接將結(jié)果返回出去,且不會(huì)繼續(xù)向下執(zhí)行
  • 然后執(zhí)行 方法體 ,如果有多個(gè),則依次全部執(zhí)行,并返回最后一個(gè)不為空的結(jié)果
  • 執(zhí)行 after 鉤子,并傳入 方法體 的執(zhí)行結(jié)果
  • 如果是 Api 上的異步方法,還會(huì)根據(jù)結(jié)果回調(diào)(success|fail)在執(zhí)行 complete 鉤子

MpKit內(nèi)置了很多鉤子,用于全局事件觸發(fā)、方法重寫等,同時(shí)你可以添加自己的鉤子函數(shù),調(diào)用:

MpKit.MixinStore.addHook(type:MpViewType.App|MpViewType.Page|MpViewType.Component|'Api', hook:MpMethodHook) 可為 App/Page/Component/Api 添加全局鉤子函數(shù); MpMethodHook 的定義如下:

interface MpMethodHookLike {
    before?(
        methodName: string,
        methodArgs: any[],
        methodHandler: Function,
        funId?: string
    );
    after?(
        methodName: string,
        methodArgs: any[],
        methodResult: any,
        funId?: string
    );
    catch?(
        methodName: string,
        methodArgs: any[],
        error: Error,
        errType?: string,
        funId?: string
    );
    complete?(
        methodName: string,
        methodArgs: any[],
        res: any,
        success?: boolean,
        funId?: string
    );
}
interface MpMethodHook extends MpMethodHookLike {
    [prop: string]: Function | MpMethodHookLike;
}

示例1:

import MpKit from "@mpkit/inject/dist/index";
import { MpViewType } from "@mpkit/inject/dist/types";
MpKit.MixinStore.addHook(MpViewType.App, {
    before(methodName, methodArgs) {
        console.log(`before methodName=${methodName}`);
    },
    after(methodName, methodArgs, methodResult) {
        console.log(`after methodName=${methodName}, ${methodResult}`);
    },
    catch(methodName, methodArgs, error) {
        console.log(`catch err=${error.message}`);
    },
});
App(
    MpKit.App({
        onLaunch() {
            this.add(1, 2);
        },
        onShow() {
            throw new Error("test");
        },
        add(a, b) {
            return a + b;
        },
    })
);
// 輸出:before methodName=onLaunch
// 輸出:before methodName=add
// 輸出:after methodName=add, 2
// 輸出:after methodName=onLaunch,
// 輸出:before methodName=onShow,
// 輸出:catch err=test

MpKit.MixinStore.addHook("Api", {
    before(methodName, methodArgs, methodHandler, funId) {
        console.log(`before api=${methodName}`);
    },
    after(methodName, methodArgs, methodResult, funId) {
        console.log(`after api=${methodName}, ${methodResult}`);
    },
    complete(methodName, methodArgs, res, isSuccess, funId) {
        console.log(`complete api=${methodName}, ${isSuccess}, ${res}`);
    },
});
MpKit.Api.request({
    url: "...",
});
// 輸出:before api=request
// 輸出:after api=request, [RequestTask Object]
// 假設(shè)請(qǐng)求成功且返回字符串“1”,則輸出:complete api=request, true, 1
// 假設(shè)請(qǐng)求失敗,則輸出:complete api=request, false, { errMsg:'...' }

示例2:當(dāng)在 before 鉤子中返回 false 會(huì)具體值時(shí):

MpKit.MixinStore.addHook(MpViewType.App, {
    onShow: {
        before(methodName, methodArgs) {
            console.log("hook onShow");
            return false;
        },
    },
});
App(
    MpKit.App({
        onLaunch() {},
        onShow() {
            console.log("self onShow");
        },
    })
);
// 僅輸出:hook onShow

const store = {};
MpKit.MixinStore.addHook("Api", {
    before(methodName, methodArgs, methodHandler, funId) {
        console.log(`before methodName=${methodName}`);
        if (methodName === "setStorageSync") {
            store[methodArgs[0]] = methodArgs[1];
        }
        if (methodName === "getStorageSync") {
            // 并不會(huì)真正執(zhí)行(wx|my|tt|..).getStorageSync
            return store[methodArgs[0]];
        }
    },
    after(methodName) {
        console.log(`after methodName=${methodName}`);
    },
});
MpKit.Api.setStorageSync("name", "Tom");
const name = MpKit.Api.getStorageSync("name");
console.log(name === store.name);
// 輸出:before methodName=setStorageSync
// 輸出:after methodName=setStorageSync
// 輸出:before methodName=getStorageSync
// 輸出:true

結(jié)語

希望MpKit可以為你帶來便捷愉快的開發(fā)體驗(yàn),祝大家工作順心,家庭美滿,加油!

相關(guān)案例查看更多