Heim  >  Artikel  >  WeChat-Applet  >  Ausführliche Erklärung zum Hinzufügen von Mixin-Erweiterungen in der WeChat-Applet-Entwicklung

Ausführliche Erklärung zum Hinzufügen von Mixin-Erweiterungen in der WeChat-Applet-Entwicklung

黄舟
黄舟Original
2017-09-12 11:27:252341Durchsuche

Mixin ist eine Idee, die teilweise implementierte Schnittstellen verwendet, um die Wiederverwendung von Code zu erreichen. Es kann zur Lösung des Problems der Mehrfachvererbung und zur Funktionserweiterung verwendet werden. Der folgende Artikel führt Sie hauptsächlich in die relevanten Informationen zum Hinzufügen von Mixin-Erweiterungen zu WeChat-Miniprogrammen ein. Freunde, die diese benötigen, können sich diese gemeinsam ansehen.

Einführung in Mixin

Der Mixin-Modus (Weben) ist keine der „Design Patterns“-Zusammenfassungen von GOF, wird aber in verschiedenen Sprachen verwendet ​​und Frameworks werden dieses Muster (oder diese Idee) in gewisser Weise anwenden. Einfach ausgedrückt ist Mixin eine Schnittstelle mit vollständiger oder teilweiser Implementierung, und ihre Hauptfunktion ist eine bessere Wiederverwendung von Code.

Das Konzept von Mixin wird in React und Vue unterstützt. Es bietet uns Komfort bei der Abstraktion von Geschäftslogik und der Wiederverwendung von Code. Das native Mini-Programm-Framework unterstützt Mixin jedoch nicht direkt. Schauen wir uns zunächst eine sehr praktische Anforderung an:

Fügen Sie allen Miniprogrammseiten eine Laufumgebungsklasse hinzu, um einige Stil-Hacks zu ermöglichen. Insbesondere wenn das Miniprogramm in verschiedenen Betriebsumgebungen (Entwicklertools|iOS|Android) ausgeführt wird, ist der Plattformwert der entsprechende Betriebsumgebungswert („ios|android|devtools“)


<view class="{{platform}}">
 <!--页面模板-->
</view>

Überprüfung der Verwendung von Mixins in Vue

Die am Anfang des Artikels genannten Probleme eignen sich sehr gut, um mit Mixins gelöst zu werden. Wir haben diese Anforderung in ein Vue-Problem umgewandelt: Fügen Sie jeder Routing-Seite eine Klasse im Plattformstil hinzu (obwohl dies möglicherweise nicht praktikabel ist). Die Implementierungsidee besteht darin, jeder Routing-Komponente ein data: platform hinzuzufügen. Der Code ist wie folgt implementiert:


// mixins/platform.js
const getPlatform = () => {
 // 具体实现略,这里mock返回&#39;ios&#39;
 return &#39;ios&#39;;
};

export default {
 data() {
 return {
  platform: getPlatform()
 }
 }
}


// 在路由组件中使用
// views/index.vue
import platform from &#39;mixins/platform&#39;;

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


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

In Auf diese Weise verfügt das ViewModel beider Detail-Routing-Seiten im Index über den Wert platform, der direkt im Template verwendet werden kann.

Mixin-Klassifizierung in Vue

  • Daten-Mixin

  • normale Methode mixin

  • Lebenszyklusmethode mixin

im Code ausgedrückt ist wie folgt:


export default {
 data () {
 return {
  platform: &#39;ios&#39;
 }
 },
 methods: {
 sayHello () {
  console.log(`hello!`)
 }
 },

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

Mixin-Zusammenführungs- und Ausführungsstrategien in Vue

Wenn es Duplikate zwischen Mixins gibt, verfügen diese Mixins über spezifische Zusammenführungs- und Ausführungsstrategien. Wie unten gezeigt:

Wie man das Applet dazu bringt, Mixin zu unterstützen

Im vorherigen Artikel haben wir es besprochen vue Wissen über Mixins. Jetzt müssen wir dafür sorgen, dass das Miniprogramm auch Mixin unterstützt und die gleiche Mixin-Funktion in Vue realisieren.

Implementierungsideen

Werfen wir zunächst einen Blick auf die offizielle Registrierungsmethode für die Seite des Miniprogramms:


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: &#39;MINA&#39;
 }
})

Wenn wir die Mixin-Konfiguration hinzufügen, lautet die oben genannte offizielle Registrierungsmethode:


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: &#39;MINA&#39;
 }
})

Hier gibt es zwei Punkte, auf die wir besonders achten sollten Achtung:

  • Page(configObj) - Konfigurieren Sie die Daten, Methode, Lebenszyklus usw. der Applet-Seite über configObj

  • onLoad-Methode – Haupteingang der Seite

Wenn Sie möchten, dass die Definition im Mixin gültig ist, müssen Sie viel Aufhebens machen, bevor configObj offiziell an Page() übergeben wird. Tatsächlich ist Page(configObj) ein gewöhnlicher Funktionsaufruf:


Page(createPage(configObj))

In der createPage-Methode können wir das Mixin in configObj vorverarbeiten Fügen Sie die Konfiguration korrekt in configObj ein und übergeben Sie sie schließlich an Page() . Dies ist die Idee der Implementierung von Mixins.

Spezifische Implementierung

Die spezifische Code-Implementierung wird nicht im Detail beschrieben. Sie können den folgenden Code sehen. Eine detailliertere Code-Implementierung, weitere Erweiterungen und Tests finden Sie unter github >1. In diesem Artikel geht es hauptsächlich darum, wie man kleinen Programmen Mixin-Unterstützung hinzufügt. Die Implementierungsidee lautet: Vorverarbeitung von configObj


/**
 * 为每个页面提供mixin,page invoke桥接
 */

const isArray = v => Array.isArray(v);
const isFunction = v => typeof v === &#39;function&#39;;
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));
}


// 页面堆栈
const pagesStack = getApp().$pagesStack;

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

const onLoad = function (opts) {
 // 把pageModel放入页面堆栈
 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方法会被丢弃
  if (key === &#39;onLoad&#39;) return;

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

 // 提取lifecycle
 PAGE_EVENT.forEach(key => {
  if (isFunction(mixin[key]) && key !== &#39;onLoad&#39;) {
  if (ret[key]) {
   // 多个mixin有相同lifecycle时,将方法转为数组存储
   ret[key] = ret[key].concat(mixin[key]);
  } else {
   ret[key] = [mixin[key]];
  }
  }
 })
 });

 return ret;
};

/**
 * 重复冲突处理借鉴vue:
 * data, methods会合并,组件自身具有最高优先级,其次mixins中后配置的mixin优先级较高
 * lifecycle不会合并。先顺序执行mixins中的lifecycle,再执行组件自身的lifecycle
 */

const mixData = (minxinData, nativeData) => {
 Object.keys(minxinData).forEach(key => {
 // page中定义的data不会被覆盖
 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;
};

2. Achten Sie bei der Verarbeitung von Mixin-Duplikationen auf Vue: Daten, Methoden Wann Zusammengeführt hat die Komponente selbst die höchste Priorität, gefolgt von dem später in den Mixins konfigurierten Mixin.

Lebenszyklen werden nicht zusammengeführt. Führen Sie zuerst den Lebenszyklus in den Mixins nacheinander aus und führen Sie dann den Lebenszyklus der Komponente selbst aus.


Zusammenfassung

Page(createPage(configObj))

Das obige ist der detaillierte Inhalt vonAusführliche Erklärung zum Hinzufügen von Mixin-Erweiterungen in der WeChat-Applet-Entwicklung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn