亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

微信小程序開發(fā)教程之增加mixin擴(kuò)展

 更新時(shí)間:2017年08月09日 09:19:00   作者:u3xyz  
Mixin是一種思想,用部分實(shí)現(xiàn)的接口來實(shí)現(xiàn)代碼復(fù)用??梢杂脕斫鉀Q多繼承的問題,又可以用來擴(kuò)展功能。下面這篇文章主要給大家介紹了關(guān)于為微信小程序增加mixin擴(kuò)展的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。

Mixin簡(jiǎn)介

Mixin(織入)模式并不是GOF的《設(shè)計(jì)模式》歸納中的一種,但是在各種語(yǔ)言以及框架都會(huì)發(fā)現(xiàn)該模式(或者思想)的一些應(yīng)用。簡(jiǎn)單來說,Mixin是帶有全部實(shí)現(xiàn)或者部分實(shí)現(xiàn)的接口,其主要作用是更好的代碼復(fù)用。

Mixin這個(gè)概念在React, Vue中都有支持,它為我們抽象業(yè)務(wù)邏輯,代碼復(fù)用提供了方便。然而小程序原生框架并沒直接支持Mixin。我們先看一個(gè)很實(shí)際的需求:

為所有小程序頁(yè)面增加運(yùn)行環(huán)境class,以方便做一些樣式hack。具體說就是小程序在不同的運(yùn)行環(huán)境(開發(fā)者工具|iOS|Android)運(yùn)行時(shí),platform值為對(duì)應(yīng)的運(yùn)行環(huán)境值("ios|android|devtools")

<view class="{{platform}}">
 <!--頁(yè)面模板-->
</view>

回顧vue中mixin的使用

文章開始提到的問題是非常適合使用Mixin來解決的。我們把這個(gè)需求轉(zhuǎn)換成一個(gè)Vue問題:在每個(gè)路由頁(yè)面中增加一個(gè)platform的樣式class(雖然這樣做可能沒實(shí)際意義)。實(shí)現(xiàn)思路就是為每個(gè)路由組件增加一個(gè)data: platform。代碼實(shí)現(xiàn)如下:

// mixins/platform.js
const getPlatform = () => {
 // 具體實(shí)現(xiàn)略,這里mock返回'ios'
 return 'ios';
};

export default {
 data() {
 return {
  platform: getPlatform()
 }
 }
}
// 在路由組件中使用
// views/index.vue
import platform from 'mixins/platform';

export default {
 mixins: [platform],
 // ...
}
// 在路由組件中使用
// views/detail.vue
import platform from 'mixins/platform';

export default {
 mixins: [platform],
 // ...
}

這樣,在index,detail兩個(gè)路由頁(yè)的viewModel上就都有platform這個(gè)值,可以直接在模板中使用。

vue中mixin分類

  • data mixin
  • normal method mixin
  • lifecycle method mixin

用代碼表示的話,就如:

export default {
 data () {
 return {
  platform: 'ios'
 }
 },

 methods: {
 sayHello () {
  console.log(`hello!`)
 }
 },

 created () {
 console.log(`lifecycle3`)
 }
}

vue中mixin合并,執(zhí)行策略

如果mixin間出現(xiàn)了重復(fù),這些mixin會(huì)有具體的合并,執(zhí)行策略。如下圖:

如何讓小程序支持mixin

在前面,我們回顧了vue中mixin的相關(guān)知識(shí)?,F(xiàn)在我們要讓小程序也支持mixin,實(shí)現(xiàn)vue中一樣的mixin功能。

實(shí)現(xiàn)思路

我們先看一下官方的小程序頁(yè)面注冊(cè)方式:

Page({
 data: {
 text: "This is page data."
 },
 onLoad: function(options) {
 // Do some initialize when page load.
 },
 onReady: function() {
 // Do something when page ready.
 },
 onShow: function() {
 // Do something when page show.
 },
 onHide: function() {
 // Do something when page hide.
 },
 onUnload: function() {
 // Do something when page close.
 },
 customData: {
 hi: 'MINA'
 }
})

假如我們加入mixin配置,上面的官方注冊(cè)方式會(huì)變成:

Page({
 mixins: [platform],
 data: {
 text: "This is page data."
 },
 onLoad: function(options) {
 // Do some initialize when page load.
 },
 onReady: function() {
 // Do something when page ready.
 },
 onShow: function() {
 // Do something when page show.
 },
 onHide: function() {
 // Do something when page hide.
 },
 onUnload: function() {
 // Do something when page close.
 },
 customData: {
 hi: 'MINA'
 }
})

這里有兩個(gè)點(diǎn),我們要特別注意:

  • Page(configObj) - 通過configObj配置小程序頁(yè)面的data, method, lifecycle等
  • onLoad方法 - 頁(yè)面main入口

要想讓mixin中的定義有效,就要在configObj正式傳給Page()之前做文章。其實(shí)Page(configObj)就是一個(gè)普通的函數(shù)調(diào)用,我們加個(gè)中間方法:

Page(createPage(configObj))

在createPage這個(gè)方法中,我們可以預(yù)處理configObj中的mixin,把其中的配置按正確的方式合并到configObj上,最后交給Page() 。這就是實(shí)現(xiàn)mixin的思路。

具體實(shí)現(xiàn)

具體代碼實(shí)現(xiàn)就不再贅述,可以看下面的代碼。更詳細(xì)的代碼實(shí)現(xiàn),更多擴(kuò)展,測(cè)試可以參看github

/**
 * 為每個(gè)頁(yè)面提供mixin,page invoke橋接
 */

const isArray = v => Array.isArray(v);
const isFunction = v => typeof v === 'function';
const noop = function () {};

// 借鑒redux https://github.com/reactjs/redux
function compose(...funcs) {
 if (funcs.length === 0) {
 return arg => arg;
 }

 if (funcs.length === 1) {
 return funcs[0];
 }

 const last = funcs[funcs.length - 1];
 const rest = funcs.slice(0, -1);
 return (...args) => rest.reduceRight((composed, f) => f(composed), last(...args));
}


// 頁(yè)面堆棧
const pagesStack = getApp().$pagesStack;

const PAGE_EVENT = ['onLoad', 'onReady', 'onShow', 'onHide', 'onUnload', 'onPullDownRefresh', 'onReachBottom', 'onShareAppMessage'];
const APP_EVENT = ['onLaunch', 'onShow', 'onHide', 'onError'];

const onLoad = function (opts) {
 // 把pageModel放入頁(yè)面堆棧
 pagesStack.addPage(this);

 this.$invoke = (pagePath, methodName, ...args) => {
 pagesStack.invoke(pagePath, methodName, ...args);
 };

 this.onBeforeLoad(opts);
 this.onNativeLoad(opts);
 this.onAfterLoad(opts);
};

const getMixinData = mixins => {
 let ret = {};

 mixins.forEach(mixin => {
 let { data={} } = mixin;

 Object.keys(data).forEach(key => {
  ret[key] = data[key];
 });
 });

 return ret;
};

const getMixinMethods = mixins => {
 let ret = {};

 mixins.forEach(mixin => {
 let { methods={} } = mixin;

 // 提取methods
 Object.keys(methods).forEach(key => {
  if (isFunction(methods[key])) {
  // mixin中的onLoad方法會(huì)被丟棄
  if (key === 'onLoad') return;

  ret[key] = methods[key];
  }
 });

 // 提取lifecycle
 PAGE_EVENT.forEach(key => {
  if (isFunction(mixin[key]) && key !== 'onLoad') {
  if (ret[key]) {
   // 多個(gè)mixin有相同lifecycle時(shí),將方法轉(zhuǎn)為數(shù)組存儲(chǔ)
   ret[key] = ret[key].concat(mixin[key]);
  } else {
   ret[key] = [mixin[key]];
  }
  }
 })
 });

 return ret;
};

/**
 * 重復(fù)沖突處理借鑒vue:
 * data, methods會(huì)合并,組件自身具有最高優(yōu)先級(jí),其次mixins中后配置的mixin優(yōu)先級(jí)較高
 * lifecycle不會(huì)合并。先順序執(zhí)行mixins中的lifecycle,再執(zhí)行組件自身的lifecycle
 */

const mixData = (minxinData, nativeData) => {
 Object.keys(minxinData).forEach(key => {
 // page中定義的data不會(huì)被覆蓋
 if (nativeData[key] === undefined) {
  nativeData[key] = minxinData[key];
 }
 });

 return nativeData;
};

const mixMethods = (mixinMethods, pageConf) => {
 Object.keys(mixinMethods).forEach(key => {
 // lifecycle方法
 if (PAGE_EVENT.includes(key)) {
  let methodsList = mixinMethods[key];

  if (isFunction(pageConf[key])) {
  methodsList.push(pageConf[key]);
  }

  pageConf[key] = (function () {
  return function (...args) {
   compose(...methodsList.reverse().map(f => f.bind(this)))(...args);
  };
  })();
 }

 // 普通方法
 else {
  if (pageConf[key] == null) {
  pageConf[key] = mixinMethods[key];
  }
 }
 });

 return pageConf;
};

export default pageConf => {

 let {
 mixins = [],
 onBeforeLoad = noop,
 onAfterLoad = noop
 } = pageConf;

 let onNativeLoad = pageConf.onLoad || noop;
 let nativeData = pageConf.data || {};

 let minxinData = getMixinData(mixins);
 let mixinMethods = getMixinMethods(mixins);

 Object.assign(pageConf, {
 data: mixData(minxinData, nativeData),
 onLoad,
 onBeforeLoad,
 onAfterLoad,
 onNativeLoad,
 });

 pageConf = mixMethods(mixinMethods, pageConf);

 return pageConf;
};

小結(jié)

1、本文主要講了如何為小程序增加mixin支持。實(shí)現(xiàn)思路為:預(yù)處理configObj

Page(createPage(configObj))

2、在處理mixin重復(fù)時(shí),與vue保持一致:

      data, methods會(huì)合并,組件自身具有最高優(yōu)先級(jí),其次mixins中后配置的mixin優(yōu)先級(jí)較高。

      lifecycle不會(huì)合并。先順序執(zhí)行mixins中的lifecycle,再執(zhí)行組件自身的lifecycle。

總結(jié)

好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

  • JavaScript實(shí)現(xiàn)簡(jiǎn)單的拖拽效果

    JavaScript實(shí)現(xiàn)簡(jiǎn)單的拖拽效果

    這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)簡(jiǎn)單的拖拽效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Javascript函數(shù)緩存的實(shí)現(xiàn)及應(yīng)用場(chǎng)景

    Javascript函數(shù)緩存的實(shí)現(xiàn)及應(yīng)用場(chǎng)景

    Javascript函數(shù)緩存是一種提高網(wǎng)頁(yè)性能的重要技術(shù),通過將函數(shù)結(jié)果存儲(chǔ)在緩存中,避免重復(fù)計(jì)算,從而提高頁(yè)面加載速度和響應(yīng)速度,本文主要介紹了Javascript函數(shù)緩存的實(shí)現(xiàn)及應(yīng)用場(chǎng)景,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • 小程序云開發(fā)之用戶注冊(cè)登錄

    小程序云開發(fā)之用戶注冊(cè)登錄

    這篇文章主要為大家詳細(xì)介紹了小程序云開發(fā)之用戶注冊(cè)登錄,帶云數(shù)據(jù)庫(kù)配置,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-05-05
  • 微信小程序使用canvas繪制鐘表

    微信小程序使用canvas繪制鐘表

    這篇文章主要為大家詳細(xì)介紹了微信小程序使用canvas繪制鐘表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-05-05
  • 微信小程序自定義頭部導(dǎo)航欄(組件化)

    微信小程序自定義頭部導(dǎo)航欄(組件化)

    這篇文章主要為大家詳細(xì)介紹了微信小程序自定義頭部導(dǎo)航欄,膠囊按鈕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Sublime?Text?3插件Minify的安裝與使用(js代碼壓縮)

    Sublime?Text?3插件Minify的安裝與使用(js代碼壓縮)

    這篇文章主要介紹了Sublime?Text?3插件Minify的安裝與使用(js代碼壓縮),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-01-01
  • 分享Javascript中最常用的55個(gè)經(jīng)典小技巧

    分享Javascript中最常用的55個(gè)經(jīng)典小技巧

    這篇文章主要介紹了Javascript中最常用的55個(gè)經(jīng)典小技巧。需要的朋友可以過來參考下,希望對(duì)大家有所幫助
    2013-11-11
  • JS的replace方法介紹

    JS的replace方法介紹

    replace() 方法的參數(shù) replacement 可以是函數(shù)而不是字符串。在這種情況下,每個(gè)匹配都調(diào)用該函數(shù),它返回的字符串將作為替換文本使用
    2012-10-10
  • 克隆javascript對(duì)象的三個(gè)方法小結(jié)

    克隆javascript對(duì)象的三個(gè)方法小結(jié)

    克隆javascript對(duì)象的三個(gè)方法整理,需要的朋友可以參考下。
    2011-01-01
  • javascript xml為數(shù)據(jù)源的下拉框控件

    javascript xml為數(shù)據(jù)源的下拉框控件

    此控件以xml為數(shù)據(jù)源,可以進(jìn)行輸入的多屬性自動(dòng)適配
    2009-07-07

最新評(píng)論