黔优媒体网-软文媒体自助发稿平台!
  1. 行业资讯
  2. 正文

微信小程序开发中关于增加mixin扩展的详解

来源:黔优媒体网   时间:2024-09-19

mixin是一种思想,用部分实现的接口来实现代码复用。可以用来解决多继承的问题,又可以用来扩展功能。下面这篇文章主要给大家介绍了关于为微信小程序增加mixin扩展的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。

Mixin简介

Mixin(织入)模式并不是GOF的《设计模式》归纳中的一种,但是在各种语言以及框架都会发现该模式(或者思想)的一些应用。简单来说,Mixin是带有全部实现或者部分实现的接口,其主要作用是更好的代码复用。

Mixin这个概念在React, Vue中都有支持,它为我们抽象业务逻辑,代码复用提供了方便。然而小程序原生框架并没直接支持Mixin。我们先看一个很实际的需求:

为所有小程序页面增加运行环境class,以方便做一些样式hack。具体说就是小程序在不同的运行环境(开发者工具|iOS|Android)运行时,platform值为对应的运行环境值("ios|android|devtools")


 view >

回顾vue中mixin的使用

文章开始提到的问题是非常适合使用Mixin来解决的。我们把这个需求转换成一个Vue问题:在每个路由页面中增加一个platform的样式class(虽然这样做可能没实际意义)。实现思路就是为每个路由组件增加一个data: platform。代码实现如下:


// 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],
 // ...
}

这样,在index,detail两个路由页的viewModel上就都有platform这个值,可以直接在模板中使用。

vue中mixin分类

data mixin

normal method mixin

lifecycle method mixin

用代码表示的话,就如:


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

vue中mixin合并,执行策略

如果mixin间出现了重复,这些mixin会有具体的合并,执行策略。如下图:

如何让小程序支持mixin

在前面,我们回顾了vue中mixin的相关知识。现在我们要让小程序也支持mixin,实现vue中一样的mixin功能。

实现思路

我们先看一下官方的小程序页面注册方式:


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;
})

假如我们加入mixin配置,上面的官方注册方式会变成:


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;
})

这里有两个点,我们要特别注意:

Page(configObj) - 通过configObj配置小程序页面的data, method, lifecycle等

onLoad方法 - 页面main入口

要想让mixin中的定义有效,就要在configObj正式传给Page()之前做文章。其实Page(configObj)就是一个普通的函数调用,我们加个中间方法:


Page(createPage(configObj))

在createPage这个方法中,我们可以预处理configObj中的mixin,把其中的配置按正确的方式合并到configObj上,最后交给Page() 。这就是实现mixin的思路。

具体实现

具体代码实现就不再赘述,可以看下面的代码。更详细的代码实现,更多扩展,测试可以参看github


/**
 * 为每个页面提供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 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; };

小结

1、本文主要讲了如何为小程序增加mixin支持。实现思路为:预处理configObj


Page(createPage(configObj))

2、在处理mixin重复时,与vue保持一致:

      data, methods会合并,组件自身具有最高优先级,其次mixins中后配置的mixin优先级较高。

      lifecycle不会合并。先顺序执行mixins中的lifecycle,再执行组件自身的lifecycle。

总结

以上就是微信小程序开发中关于增加mixin扩展的详解的详细内容,更多请关注php中文网其它相关文章!

微信app下载

微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!


【免责申明】黔优媒体网以上展示内容来源于用户自主上传、合作媒体、企业机构或网络收集整理,版权争议与本站无关,文章涉及见解与观点不代表黔优媒体网官方立场,请读者仅做参考,本文标题:微信小程序开发中关于增加mixin扩展的详解;欢迎转载,转载时请说明出处。若您认为本文侵犯了您的版权信息,或您发现该内容有任何违法/违规的内容,请您立即联系我们及时修正或删除。(邮箱号: kefu@qianu.com)
此操作需要登录,请先登录~
免费注册会员,尽享国内领先平台!