zoukankan      html  css  js  c++  java
  • 微信小程序2

    官方默认的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
      1 /**
      2  * 全局初始化界面函数,供页面调用
      3  * PageOption = {
      4  *  needLogin:false,  //是否需要登录
      5  *  loginReturnUrl: null  // 登录成功后,需要跳转回的页面,可以是function ,为空则返回默认页面
      6  * 
      7  * }
      8  * 
      9  */
     10 BasePageOptionClass.initPage = function (PageOption ) {
     11     var app = getApp();
     12     PageOption = PageOption || {};
     13  
     14         var actualOption = new BasePageOptionClass(PageOption.data);
     15         actualOption.PageOption = PageOption;
     16         var wxFunctions = {
     17             "onLoad": 1, "onReady": 1, "onShow": 1, "onHide": 1, "onUnload": 1, 
     18       "onPullDownRefresh": 1, "onReachBottom": 1 , "onShareAppMessage": 1, "onPageScroll": 1
     19         };
     20     for (var key in PageOption) {
     21       if (!wxFunctions[key]) {
     22         const functionKey = key;
     23         actualOption[functionKey] = actualOption.PageOption[functionKey]
     24       }
     25     }
     26 
     27         for (var functionKey in wxFunctions) {
     28       const key = functionKey;  // 这里要一个临时常量,否则执行的时候,functionKey永远是最后一个
     29       if (!PageOption[key]){  //如果 参数没有,而基类有,那么保持基类不变
     30         if (actualOption[key]) {  //目前只有 onShareAppMessage 是底层封装好的
     31           continue;
     32         }
     33       }
     34       //否则重写基类方法
     35       Object.defineProperty(actualOption, key, {
     36         configurable: true  ,
     37         enumerable: true  ,
     38         value: function () {
     39           var $target = this;  //这里的 $target 可以认为是  BasePageOptionClass实例, 实际上,在运行时,已经转变为 Page对象
     40           try { 
     41             //处理通知消息
     42             if("onLoad"==key){  //当页面第一次打开的时候,注册 以 当前页 route 为 name的通知事件,通知内部做了 获取未处理消息的机制,如果有未处理的消息,那么立即执行
     43               $target.addNotifyListener($target.getCurrentPageUrl());
     44             } else if ("onUnload" == key) {
     45               //页面销毁的时候,销毁所有已注册的通知
     46               $target.removeNotifyListener(); 
     47             }
     48             // 嵌入了 前置处理程序,如果注册了 , 必须有 返回值 true | false , 如 before_onLoad , 参数和 原始方法保持一致,类 拦截器,暂时未支持栈,只支持一个
     49             var canContinueRun = BasePageOptionClass.wrapPageLifeCircle(key, $target)
     50             if (!canContinueRun) {
     51               console.log("前置处理未通过,方法 " + currUrl + "  " + key)
     52               return;
     53             } 
     54             //这里要使用 actualOption ,不能用 $target ,在页面带有 component 时 , 会冲突掉 PageOption
     55             var func = actualOption.PageOption[key];
     56             if (func && func!=null) {
     57               console.log("初始化方法 " + key + " 执行 ")
     58               func.apply($target, arguments);
     59             }
     60           } catch (err) {
     61             console.log(key + "", err);
     62           }
     63         },
     64         writable:  false
     65       }); 
     66         }
     67     // console.log(actualOption)
     68   return actualOption;
     69 }
     70 
     71 
     72 
     73 BasePageOptionClass.wrapPageLifeCircle = function (LifeCircleFuncName, PageOption={}) {
     74     var canContinueRun = true;
     75   var app = getApp();
     76     // console.log(LifeCircleFuncName)
     77   
     78   if (PageOption.needLogin) {  //是否需要登录 
     79         // console.log("执行前置")
     80     if ("onLoad" == LifeCircleFuncName || "onShow" == LifeCircleFuncName) {  //在onload 事件之前做 登录判断
     81             var xgUserInfo = app.globalData.xgUserInfo;
     82             if (!xgUserInfo) {
     83         var loginReturnUrl = "/pages/my/index/index"
     84                 if (!PageOption.loginReturnUrl) {
     85             loginReturnUrl = PageOption.loginReturnUrl;
     86                 } else { 
     87                     if (typeof loginReturnUrl === "function") {
     88             loginReturnUrl = (loginReturnUrl)();
     89                     } else {
     90             loginReturnUrl = "/pages/my/index/index"
     91                     }
     92                 }
     93         wx.reLaunch({
     94           url: "/pages/my/register/index?returnUrl=" + loginReturnUrl
     95         });
     96                 canContinueRun = false;
     97             }
     98         } 
     99     } 
    100   if (!canContinueRun) return canContinueRun;
    101 
    102   var func = "before_" + LifeCircleFuncName;
    103   var pf = PageOption[func];
    104   if (pf && pf!=null){ // 带有before_ 开头的对应的内置方法,作为前置判断 , 需要有返回值
    105     var ret = pf.apply(PageOption, []);
    106     if(ret!==undefined){
    107       if (!ret) canContinueRun=false;
    108     }
    109   } 
    110   // app.util.log("进入前置", LifeCircleFuncName)
    111     return canContinueRun;
    112 }
    这个方法的核心完成了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);
         
    }                    
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    请用正则实现String.trim()
    事件委托的原理是什么?有什么作用?
    请简述get请求和post请求的区别
    用原生js实现,点击一个列表时,输出对应的索引
    请用js写一个函数,实现获取浏览器url中查询字符串中的参数并返回一个数组
    请描述一下cookies、sessionStorage、localStorage、session四者的区别?
    清除浮动的几种方式,各自的优缺点?
    如何使用离线存储(localStorage)?
    使用css怎么让谷歌支持小于12px的文字比如10px
    ajax有哪些方法可以实现跨域?他们都有哪些局限性?
  • 原文地址:https://www.cnblogs.com/jifsu/p/7850811.html
Copyright © 2011-2022 走看看