评论

重用你的Page(viewController/Activity)

重用page()函数,却不增加page本身业务的复杂度

重用你的Page(viewController/Activity)

在应用开发的过程中,我们经常遇到一种场景:根据进来的场景不同,页面的点击事件会有不同的业务逻辑。
因为最近在写小程序,就以小程序为例。小程序与iOS的UI架构类似,在小程序中充当UIViewController角色的函数叫做Page。

//A.wxml
<view>A</view>
<button bind:tap="onJump">跳转目标页</button>
//A.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  /**
   * 跳转到目标页
   */
  onJump() {
    wx.navigateTo({
      url: '../index/index?source=A',
    })
  }
})
  
//B.wxml
<view>B</view>
<button bind:tap="onJump">跳转目标页</button>
//B.js
Page({

  /**
   * 页面的初始数据
   */
  data: {

  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {

  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },
  /**
   * 跳转到目标页
   */
  onJump() {
    wx.navigateTo({
      url: '../index/index?source=B',
    })
  }
})
  
//index.js

Page({
  source: '', //进入页面的来源
  data: {
    
  },
  /**
   * 记录页面来源
   */
  onLoad: function (query) {
    const {source} = query;
    this.source = source;
  },
  onShow() {
 
  },
  /**
   * 上传日志
   */
  onUpload() {
    if (this.source==='A') {
      console.log('上传日志到A服务器')
    }
    if (this.source === 'B') {
      console.log('上传日志到B服务器')
    }
  }
  

})

代码如上,它实现的需求就是:根据不同的进入来源,将日志上传到不同的服务器。从代码的实现来看,是没有什么问题的。有问题的是:无法不改变代码的情况下进行需求迭代。
比如说过了一段时间,新增需求:有一个页面C,也可以跳转目标,并且在点击上传的时候,将日志上传到C服务器。这个时候就要将index.js进行修改:

/**
   * 上传日志
   */
  onUpload() {
    if (this.source==='A') {
      console.log('上传日志到A服务器')
    }
    if (this.source === 'B') {
      console.log('上传日志到B服务器')
    }
    //新增C的跳转逻辑
    if (this.source === 'C') {
      console.log('上传日志到C服务器')
    }
  }

再过一点时间,又有一个新的需求:有一个页面D,也可以跳转目标,并且在点击上传的时候,将日志上传到D服务器.这个时候就要再次修改index.js文件:

/**
 * 上传日志
 */
onUpload() {
  if (this.source==='A') {
    console.log('上传日志到A服务器')
  }
  if (this.source === 'B') {
    console.log('上传日志到B服务器')
  }
  if (this.source === 'C') {
    console.log('上传日志到C服务器')
  }
  //新增D的跳转逻辑
  if (this.source === 'D') {
    console.log('上传日志到D服务器')
  }
}

随着需求的迭代,我们每次都需要修改index.js文件,然后测试代码的准确性。
这样的做法,带来几个问题:
1.随着来源的页面数量越来越多,onUpload的函数会越来越长,充斥着各种if else,不易阅读,也不易理解。
2.每次修改upload函数,都要重新测试,维护成本高。
既然有这么多的缺点,接下来,我们就使用新的代码编写方式,修复这些缺陷:
第一步,添加indexLogic.js文件

class IndexLogic {
  constructor() {
    this.uploadLog = null;
  }

}
const indexLogic = new IndexLogic();
export default indexLogic;

第二步,改造A.js,B.js文件

// A.js
import indexLogic from '../index/indexLogic.js'

...
...

onJump() {
    wx.navigateTo({
      url: '../index/index',
    })
    indexLogic.uploadLog = ()=>{
      console.log('上传日志到A服务器')
    }
  }
// B.js
import indexLogic from '../index/indexLogic.js'

...
...

onJump() {
    wx.navigateTo({
      url: '../index/index',
    })
    indexLogic.uploadLog = ()=>{
      console.log('上传日志到B服务器')
    }
  }

第三步,改造index.js文件

//index.js
import indexLogic from './indexLogic.js';

...
...

onUpload() {
    if (indexLogic.uploadLog) {
      indexLogic.uploadLog()
    }
  }

三步改造完成之后,上传按钮的事件逻辑,由原来依赖source的情况,变成依赖indexLogic.uploadLog函数,而函数的内容则由传入页确定。以后无论传入C,D,E,F…几百个页面,上传的逻辑都由传入页决定和写入,而不需要修改index.js文件。

改造完

最后一次编辑于  03-26  
点赞 1
收藏
评论

1 个评论

  • 『小名片』
    『小名片』
    2天前

    非常好,清晰易懂

    2天前
    赞同
    回复
登录 后发表内容