官方默认的Page初始代码为

var option = {
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*
*/
onLoad: function (options) {
}
 // ... 其他生命周期函数,以及自定义 方法
}
Page(option);
其中: option中的函数,在运行期,this 指向 当前Page对象
 
扩展思路: 对Page页面提供的PageOption 再次包装
编码要求:
     option不再是一个独立定义的对象,而是经过方法创建
     整个创建过程,你可以认为类似 继承 , decorator包装器 等... , 创建类名称 /util/BasePageOptionClass.js
BasePageOptionClass 类中包含了微信小程序中所定义的所有生命周期函数的定义,并带有多个自定义的扩展函数
页面调用示例
let PageOption = {}
Page(app.BasePageOptionClass.initPage(PageOption));
核心函数 initPage
 /**
* 全局初始化界面函数,供页面调用
* PageOption = {
* needLogin:false, //是否需要登录
* loginReturnUrl: null // 登录成功后,需要跳转回的页面,可以是function ,为空则返回默认页面
*
* }
*
*/
BasePageOptionClass.initPage = function (PageOption ) {
var app = getApp();
PageOption = PageOption || {}; var actualOption = new BasePageOptionClass(PageOption.data);
actualOption.PageOption = PageOption;
var wxFunctions = {
"onLoad": 1, "onReady": 1, "onShow": 1, "onHide": 1, "onUnload": 1,
"onPullDownRefresh": 1, "onReachBottom": 1 , "onShareAppMessage": 1, "onPageScroll": 1
};
for (var key in PageOption) {
if (!wxFunctions[key]) {
const functionKey = key;
actualOption[functionKey] = actualOption.PageOption[functionKey]
}
} for (var functionKey in wxFunctions) {
const key = functionKey; // 这里要一个临时常量,否则执行的时候,functionKey永远是最后一个
if (!PageOption[key]){ //如果 参数没有,而基类有,那么保持基类不变
if (actualOption[key]) { //目前只有 onShareAppMessage 是底层封装好的
continue;
}
}
//否则重写基类方法
Object.defineProperty(actualOption, key, {
configurable: true ,
enumerable: true ,
value: function () {
var $target = this; //这里的 $target 可以认为是 BasePageOptionClass实例, 实际上,在运行时,已经转变为 Page对象
try {
//处理通知消息
if("onLoad"==key){ //当页面第一次打开的时候,注册 以 当前页 route 为 name的通知事件,通知内部做了 获取未处理消息的机制,如果有未处理的消息,那么立即执行
$target.addNotifyListener($target.getCurrentPageUrl());
} else if ("onUnload" == key) {
//页面销毁的时候,销毁所有已注册的通知
$target.removeNotifyListener();
}
// 嵌入了 前置处理程序,如果注册了 , 必须有 返回值 true | false , 如 before_onLoad , 参数和 原始方法保持一致,类 拦截器,暂时未支持栈,只支持一个
var canContinueRun = BasePageOptionClass.wrapPageLifeCircle(key, $target)
if (!canContinueRun) {
console.log("前置处理未通过,方法 " + currUrl + " " + key)
return;
}
//这里要使用 actualOption ,不能用 $target ,在页面带有 component 时 , 会冲突掉 PageOption
var func = actualOption.PageOption[key];
if (func && func!=null) {
console.log("初始化方法 " + key + " 执行 ")
func.apply($target, arguments);
}
} catch (err) {
console.log(key + "", err);
}
},
writable: false
});
}
// console.log(actualOption)
return actualOption;
} BasePageOptionClass.wrapPageLifeCircle = function (LifeCircleFuncName, PageOption={}) {
var canContinueRun = true;
var app = getApp();
// console.log(LifeCircleFuncName) if (PageOption.needLogin) { //是否需要登录
// console.log("执行前置")
if ("onLoad" == LifeCircleFuncName || "onShow" == LifeCircleFuncName) { //在onload 事件之前做 登录判断
var xgUserInfo = app.globalData.xgUserInfo;
if (!xgUserInfo) {
var loginReturnUrl = "/pages/my/index/index"
if (!PageOption.loginReturnUrl) {
loginReturnUrl = PageOption.loginReturnUrl;
} else {
if (typeof loginReturnUrl === "function") {
loginReturnUrl = (loginReturnUrl)();
} else {
loginReturnUrl = "/pages/my/index/index"
}
}
wx.reLaunch({
url: "/pages/my/register/index?returnUrl=" + loginReturnUrl
});
canContinueRun = false;
}
}
}
if (!canContinueRun) return canContinueRun; var func = "before_" + LifeCircleFuncName;
var pf = PageOption[func];
if (pf && pf!=null){ // 带有before_ 开头的对应的内置方法,作为前置判断 , 需要有返回值
var ret = pf.apply(PageOption, []);
if(ret!==undefined){
if (!ret) canContinueRun=false;
}
}
// app.util.log("进入前置", LifeCircleFuncName)
return canContinueRun;
}
这个方法的核心完成了2件事
1. 包装 Page中的PageOption内的生命周期函数(onLoad等), 使得 onLoad函数被作为 超类 onLoad 方法中的一个过程.
结构类似
BasePageOptionClass.onLoad=function(options){
//一些逻辑
//固定前置拦截器 逻辑
PageOption.onLoad(options); } BasePageOptionClass.onLoad 最终作为生命周期函数传递给Page对象

2. 增加 固定模式的前置拦截器

    这里的处理较简单, 只是增加了单个 以 before_ 开头,以生命周期函数名为结尾的函数,作为拦截器,return true | false

BasePageOptionClass.onLoad=function(options){
//一些逻辑
//固定前置拦截器 逻辑 伪代码
if(PageOption.before_onLoad){
//这里就是拦截器逻辑
var ret = PageOption.before_onLoad(option)
if(!ret){ return;
}
}
PageOption.onLoad(options); }
 
 
 
 
 
 
 
 
 

微信小程序2 - 扩展Page参数的更多相关文章

  1. 微信小程序:页面全局参数(注意不是小程序的全局变量globalData)

    为什么要使用页面全局参数:方便使用数据. 由于总页数需要再另外的一个方法中使用,所以要把总页数变成一个页面全局参数.因为取数据使用this.xxx即可,中间不用加data,给页面全局参数赋值页方便,直 ...

  2. 微信小程序 navigateTo 传对象参数

    当微信小程序navigateTo传入参数是个object时,请使用JSON.strtingify将object转化为字符串,代码如下: wx.navigateTo({ url: '../sendChe ...

  3. 微信小程序如何重写Page方法?以及重写Page方法给开发者带来的好处

    17,18年的时候,我当时主要开发小程序,那时候领导想看一下小程序的访问量,还有一些埋点的需求,于是我们的小程序就接入了阿拉丁统计. 阿拉丁的接入方式除了配置以外,主要就一行引入代码.官方要求将以下代 ...

  4. 微信小程序笔记<四>page.js —— 页面注册

    小程序的每个页面都是独立的,每个页面都必须有 page.js 和 page.wxhl 文件,page.json 和 page.wxss 文件非必要文件,注意如果创建 page.json 则至少保证有一 ...

  5. 微信小程序~页面注册page

    一 什么是page() page(),是一个函数,用来注册一个页面, 接受一个object参数, 指定页面的初始数据,生命周期函数,事件处理函数 等等 object参数说明: (1)data (obj ...

  6. 微信小程序怎么获取page/index/main后面的参数

    请求例子:page/index/main?id=123,如何获取123? mpvue框架在onLoad(options)函数里面获取options.id即可. 用的框架不同,onLoad的函数不同.原 ...

  7. 微信小程序1 - 扩展app.js

    常规的开发过程中, 每个Page的逻辑中,要使用 util.js   WapRequest.js, 需要在每个页面中书写 require('/utils/WapRequest'); 略繁琐 在app. ...

  8. 微信小程序:post请求参数放在请求体中还是拼接到URL中需要看后台是如何接收的

    前端发送post请求时,请求参数可以放在请求中,代码如下: function post(url, data, callback) { wx.request({ method: 'POST', url: ...

  9. 微信小程序navigateBack如何带参数

    wx.navigateBack({//返回 delta:1 })   方法如下: 一. var pages = getCurrentPages(); var prevPage = pages[page ...

随机推荐

  1. 转:windows BAT 批处理脚本教程

    转自:http://www.cnblogs.com/mq0036/p/3412171.html BAT 批处理脚本教程 第一章 批处理基础第一节 常用批处理内部命令简介 批处理定义:顾名思义,批处理文 ...

  2. 通过web php 执行shell脚本,获取的结果与直接在命令行下获取的结果不同。

    公司项目中的一项小功能,统计设备的连接数.其中用到shell脚本来获取已连接设备的统计.使用命令 /bin/netstat -an| grep ESTABLISHED | awk '{print $4 ...

  3. C# Meta Programming - Let Your Code Generate Code - Introduction of The Text Template Transformation Toolkit(T4)

    <#@ template language="C#" #> <#@ output extension=".cs" #> <#@ a ...

  4. java中Runtime类

    一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象, ...

  5. taro 请求函数封装

    1.项目目录 2.代码 app/src/service/api.js import Taro from '@tarojs/taro' import { HTTP_STATUS } from '../c ...

  6. vConsole

    说明 由于移动端项目在手机中调试时不能使用chrome的控制台,而vconsole是对pc端console的改写 使用方法 使用 npm 安装: npm install vconsole 使用webp ...

  7. python和c#通用一致的des加密采用CBC和PKCS7

    在python下可以下载pydes 下载地址为 http://pydes.sourceforge.net/ 在c#下实现des加密较为简单,如下: using System; using System ...

  8. Android五天乐(第二天)Activity跳转与传输数据,Fragment

    1 Activity的生命周期 activity在生命周期内共同拥有执行.暂停,和停止三种状态.每次发生状态转换时,都有一个Activity方法将状态改变的消息通知给activity.activity ...

  9. 【Linux】查询文件中指定字符串的记录

    语法 cat 文件 |grep 查询字符串 例如现在有文件file.dat,文件中内容如下: zhangsan Lisi wangwu123 wangwu890 zhangsan28290 现在想从文 ...

  10. 基于layui的框架模版,采用模块化设计,接口分离,组件化思想

    代码地址如下:http://www.demodashi.com/demo/13362.html 1. 准备工作 编辑器vscode,需要安装liveServer插件在前端开启静态服务器 或者使用hbu ...