微信小程序 扩展Page页面的Mixins

2024-04-25 10:36

本文主要是介绍微信小程序 扩展Page页面的Mixins,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前景:

在原生小程序的开发过程中,发现有很多页面使用了几乎完全一样的逻辑,例如:我们会遇到有部分功能需要登录之后才能访问,这个登录的逻辑就可以用封装成公共的逻辑,在需要的地方直接引用就可以了。

但是由于小程序官方并没有提供 Mixins 这种代码复用机制,所以只能用复制粘贴的方式去复用代码。随着功能越来越复杂,这样显得很不优雅,于是就想着怎么在小程序里面实现 Mixins。

什么是 Mixins

vue的官方定义:

混入 (mixin) 提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

vue中使用mixins

// 定义一个混入对象
var myMixin = {created: function () {this.hello()},methods: {hello: function () {console.log('hello from mixin!')}}
}// 定义一个使用混入对象的组件
var Component = Vue.extend({mixins: [myMixin]
})var component = new Component() // => "hello from mixin!"
Mixins 的机制

1、当组件和混入对象含有同名选项时,比如,数据对象在内部会进行递归合并,并在发生冲突时以组件数据优先

var mixin = {data: function () {return {message: 'hello',foo: 'abc'}}
}new Vue({mixins: [mixin],data: function () {return {message: 'goodbye',bar: 'def'}},created: function () {console.log(this.$data)// => { message: "goodbye", foo: "abc", bar: "def" }}
})

2、同名钩子函数将合并为一个数组,因此都将被调用。另外,混入对象的钩子将在组件自身钩子之前调用。

var mixin = {created: function () {console.log('混入对象的钩子被调用')}
}new Vue({mixins: [mixin],created: function () {console.log('组件钩子被调用')}
})// => "混入对象的钩子被调用"
// => "组件钩子被调用"

3、值为对象的选项,例如 methodscomponents 和 directives,将被合并为同一个对象。两个对象键名冲突时,取组件对象的键值对。

var mixin = {methods: {foo: function () {console.log('foo')},conflicting: function () {console.log('from mixin')}}
}var vm = new Vue({mixins: [mixin],methods: {bar: function () {console.log('bar')},conflicting: function () {console.log('from self')}}
})vm.foo() // => "foo"
vm.bar() // => "bar"
vm.conflicting() // => "from self"

以上是vue中Mixins 的机制

在小程序中,这套机制会和 vue的有一些区别。

在小程序中,自定义的方法是直接定义在 Page 的属性当中的,既不属于生命周期类型属性,也不属于对象类型属性。

小程序的 Mixins 运行机制多加一条:

小程序中的自定义方法,优先级为 Page > Mixins;

即 Page 中的自定义方法会覆盖 Mixins 当中的。

小程序实现方法

在小程序中,每个页面都由 Page(options) 函数定义,而 Mixins 则作用于这个函数当中的 options 对象。  

因此小程序实现 Mixins 的思路就有了——劫持并改写 Page 函数,最后再重新把它释放出来。

Mixins结构如下:

新建一个wx-mixins.js文件

import { mergeOptions } from './merge-options';// 保存原生的 Page 函数
const originPage = Page;// 重新定义 Page
Page = (options) => {// 处理 mixinsconst mixins = options.mixins;// mixins 必须为数组if (Array.isArray(mixins)) {delete options.mixins;// mixins 注入并执行相应逻辑options = merge(mixins, options);}// 释放原生 Page 函数originPage(options)
}

 新建一个merge-options.js文件

/*** 扩展 Page 的 mixins 选项* mixins 同名字段的覆盖与合并规则* 同名生命周期函数都会被调用,混入对象的生命周期函数在页面生命周期函数之前被调用* data 对象在内部会进行浅合并,并在命名发生冲突时以页面数据优先* 混入对象的属性或方法命名冲突时,页面定义的属性或方法优先*/
// Page 生命周期函数列表
const pageHooks = ["onLoad","onShow","onReady","onHide","onUnload","onPullDownRefresh","onReachBottom","onShareAppMessage","onPageScroll","onResize","onTabItemTap"
]const hasOwnProperty = Object.prototype.hasOwnProperty;
const toString = Object.prototype.toStringfunction toRawType(value) {return toString.call(value).slice(8, -1);
}function isPlainObject(value) {return toRawType(value) === "Object";
}function isFunction(value) {return toRawType(value) === "Function";
}function hasOwn(obj, key) {return hasOwnProperty.call(obj, key);
}function mergeOptions(mixins, options, hooks) {mixins.forEach(mixin => {if (!isPlainObject(mixin)) {throw new Error("typeof mixin must be plain object")}// 混入对象中嵌套混入对象,递归合并if (mixin.mixins) {mixin = mergeOptions(mixin.mixins, mixin, hooks)}// 处理混入对象中每一个值, 可能是生命周期函数、可能是 data 或 方法Object.getOwnPropertyNames(mixin).forEach(function (key) {// 暂存页面中初始的值const originValue = options[key]// 暂存混入对象的值const mixinValue = mixin[key]// 处理混入对象的生命周期函数if (pageHooks.includes(key)) {if (!isFunction(mixinValue)) {throw new Error(`typeof ${key} must be function`)}// 重写页面的生命周期函数options[key] = function () {let res;// 先执行混入对象的生命周期函数res = mixinValue.apply(this, arguments)// 后执行页面中的生命周期函数if (originValue) {res = originValue.apply(this, arguments)}return res}}// 混入对象的值是对象else if (isPlainObject(mixinValue)) {options[key] = {...mixinValue,...originValue}}// 混入对象的属性或方法else {// 页面中不存在同名的属性或方法时,才使用混入对象的属性或方法if (!hasOwn(options, key)) {options[key] = mixinValue}}})})return options
}
module.exports = {mergeOptions: mergeOptions
}
Mixins 使用

1.在小程序的 app.js 里引入 mixins.js

import './mixins/wx-mixins';

2.撰写一个 myMixin.js

// 全局app实例
const app = getApp();export default {data: {},/*** 生命周期函数--监听页面加载*/onLoad: function () {},/*** 生命周期函数--监听页面初次渲染完成*/onReady: function () {},/*** 生命周期函数--监听页面显示*/onShow: function () {},/*** 生命周期函数--监听页面隐藏*/onHide: function () {},/*** 生命周期函数--监听页面卸载*/onUnload: function () {},/*** 页面相关事件处理函数--监听用户下拉动作*/onPullDownRefresh: function () {},/*** 页面上拉触底事件的处理函数*/onReachBottom: function () {},/*** 用户点击右上角分享*/onShareAppMessage: function () {}
}

3.在 page/index/index.js 中使用

Page({mixins: [require('../../myMixin.js')]
})

这篇关于微信小程序 扩展Page页面的Mixins的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/934440

相关文章

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

使用JavaScript将PDF页面中的标注扁平化的操作指南

《使用JavaScript将PDF页面中的标注扁平化的操作指南》扁平化(flatten)操作可以将标注作为矢量图形包含在PDF页面的内容中,使其不可编辑,DynamsoftDocumentViewer... 目录使用Dynamsoft Document Viewer打开一个PDF文件并启用标注添加功能扁平化

SpringBoot如何访问jsp页面

《SpringBoot如何访问jsp页面》本文介绍了如何在SpringBoot项目中进行Web开发,包括创建项目、配置文件、添加依赖、控制层修改、测试效果以及在IDEA中进行配置的详细步骤... 目录SpringBoot如何访问JSP页python面简介实现步骤1. 首先创建的项目一定要是web项目2. 在

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

科研绘图系列:R语言扩展物种堆积图(Extended Stacked Barplot)

介绍 R语言的扩展物种堆积图是一种数据可视化工具,它不仅展示了物种的堆积结果,还整合了不同样本分组之间的差异性分析结果。这种图形表示方法能够直观地比较不同物种在各个分组中的显著性差异,为研究者提供了一种有效的数据解读方式。 加载R包 knitr::opts_chunk$set(warning = F, message = F)library(tidyverse)library(phyl

Spring框架5 - 容器的扩展功能 (ApplicationContext)

private static ApplicationContext applicationContext;static {applicationContext = new ClassPathXmlApplicationContext("bean.xml");} BeanFactory的功能扩展类ApplicationContext进行深度的分析。ApplicationConext与 BeanF

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打