小程序技能进阶回忆录 - 自主实现数据侦听器和计算器

算法蝉翼
• 阅读 2682

小程序技能进阶回忆录 - 自主实现数据侦听器和计算器

告诉元首我已尽力,告诉父亲我仍然爱他!

熟悉 Vue 的同学对 computedwatch 一定很熟悉,这些特性大大方便了我们对代码中的数据进行处理:

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})
var vm = new Vue({
  el: '#demo',
  data: {
    firstName: 'Foo',
    lastName: 'Bar',
    fullName: 'Foo Bar'
  },
  watch: {
    firstName: function (val) {
      this.fullName = val + ' ' + this.lastName
    },
    lastName: function (val) {
      this.fullName = this.firstName + ' ' + val
    }
  }
})

这是 Vue 官网中两段代码。

官方实现

如今小程序也有了自己的实现,详见官方文档 observer 。小程序官方 github
中也开源了通过 Behaviors 实现的 Vue 风格的computedwatchhttps://github.com/wechat-miniprogram/computed

那么在微信没有提供这些方法之前,如何自主实现数据的侦听器和计算属性呢?

## 自主实现

先看看定义的使用文档:

Page({
 data: {
   list: [],
   list2: [],
   size: 0
 },
 // 侦听器函数名必须跟需要被侦听的 data 对象中的属性同名,
 // 其参数中的 newValue 为属性改变后的新值,oldValue 为改变前的旧值
 watch: {
   // 如果 `list` 发生改变,这个函数就会运行
   list(newValue, oldValue) {
     console.log(oldValue + '=>' + newValue)
   }
 },
 // 传入的参数list必须是 data 里面的属性
 // 这里可以传入多个 data 属性
 computed({
   list,
   list2
 }) {
   return {
     size: list.length,
     size2: list2.length
   }
 }
})

Page 的传参中多了两个熟悉的属性,用法不用解释太多。需要继续对小程序提供的 Page 方法进行改造,此外,因为所有数据变化都会用到 setData 方法去触发,所以还需要改造这个方法。

改造 Page 和 setData

想要基于原有的 setData 进行封装,那就得先得到这个函数缓存下来(像是缓存原有的 Page 一样)。想到 onLoad 是小程序页面的第一个生命周期函数,可以在这里进行操作:

// 缓存原有的 `Page`
let originPage = Page

// 定义新的 Page
function MyPage(config) {
  let that = this
  this.watch = config.watch
  this.computed = config.computed
  this.lifetimeBackup = {
    onLoad: config.onLoad
  }
  config.onLoad = function(options) {
    // 缓存下原有的 `setData`
    this._setData = this.setData.bind(this)
    this.setData = (data) => {
      // 侦听器
      that.watching(data)
      // 计算器
      let newData = that.getComputedData(data)
      this._setData(extend(data, newData))
    }
    // 备份下页面实例
    that.context = this
    // 执行真正的 `onLoad`
    this.lifetimeBackup.onLoad.call(this, options)
  }
  
  // ...

  originPage(config)
}

MyPage.prototype.watching = funtion(data) {
  // 执行侦听器
  // ...
}

// 计算器
MyPage.prototype.getComputedData = function(data) {
  // 开始生成新的数据
  // ...
}

function page (config) {
  return new MyPage(config)
}

大致代码如上,重新定义了 this.setData,备份了原有的 setDatathis._setData。当然,这里只考虑了 setData 传一个参数的情况,多个参数需要再对代码优化下。

注意:调用 watchingcreateNewData 的对象是 that,因为 this 指向小程序页面实例,没有自定的这个方法。

做完上述改造,后续的 watchcomputed 就简单多了。

侦听器 watch

MyPage.prototype.watching = function(data) {
  var context = this.context
  var oldData = context.data
  // 开始生成新的数据
  var watch = this.watch
  if (watch) {
    Object.keys(watch).forEach(function (k) {
      // 如果新的 data 中属性被侦听,执行侦听函数
      if (k in data) {
        var newValue = data[k]
        var oldValue = oldData[k]
        watch[k].apply(context, [
          newValue,
          oldValue
        ])
      }
    })
  }
}

简易的侦听器就写好了,通过 setData 触发自定的 watch 中的侦听函数。

计算器 computed

MyPage.prototype.getComputedData = function(data) {
  var context = this.context
  var computed = this.computed
  var computedData
  if (computed) {
    computedData = computed.call(context, data)
  }
  return computedData
}

这样就得到了计算后的新生成的数据:computedData

总结

不断的通过备份、代理微信原有的方法,自主实现了简单的侦听器和计算器。当然这些代码只是为了方便分享提取出来了提供思路,实际业务中遇到情况复杂的多,代码量远远也不止这些。

点赞
收藏
评论区
推荐文章
美凌格栋栋酱 美凌格栋栋酱
7个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
梦想橡皮擦 梦想橡皮擦
4年前
13. 如果自己写的 Python 程序出错了,怎么办?
本篇文章主要内容为程序错误与异常处理,顺带会说一下内置模块logging。<center<fontcolorred缓解一下视疲劳</font</center13.如果自己写的Python程序出错了,怎么办?(https://imghelloworld.osscnbeijing.aliyuncs.com/ee1f42d25d
梦
4年前
微信小程序new Date()转换时间异常问题
微信小程序苹果手机页面上显示时间异常,安卓机正常问题image(https://imghelloworld.osscnbeijing.aliyuncs.com/imgs/b691e1230e2f15efbd81fe11ef734d4f.png)错误代码vardate'2021030617:00:00'vardateT
Jack Jack
4年前
Java 计算器小程序
该程序是一个图形界面的简单Java计算器,具有良好的界面,使用人员能快捷简单的进行加、减、乘、除、操作。其程序要求为设计一个图形界面(GUI)的计算器应用程序,完成简单的加法、减法、乘法、除法运算,且参与计算的数字和所得结果可以有小数点、正负号,同时还要具备清零功能。一、需求分析根据项目简介中的项目要求,我们将其具体需求做如下分析:1.要使用
Easter79 Easter79
3年前
Taro小程序自定义顶部导航栏
微信自带的顶部导航栏是无法支持自定义icon和增加元素的,在开发小程序的时候自带的根本满足不了需求,分享一个封装好的组件,支持自定义icon、扩展dom,适配安卓、ios、h5,全面屏。我用的是京东的Taro多端编译框架写的小程序,原生的也可以适用,用到的微信/taro的api做调整就行,实现效果如下。!在这里插入图片描述(https://i
Stella981 Stella981
3年前
Exceptionless
<divid"cnblogs\_post\_body"class"blogpostbodycnblogsmarkdown"<h1id"exceptionless.netcore开源日志框架"Exceptionless.NetCore开源日志框架</h1<blockquote<p作者:markjiang7m2<b
Stella981 Stella981
3年前
2021年全球公有云终端用户支出将增长18% ;EMNLP 2020最佳论文:无声语音的数字发声
!(https://static001.geekbang.org/infoq/af/af9f6637b50b09be60b00a42f3812d5e.png)开发者社区技术周刊又和大家见面
可莉 可莉
3年前
2021年全球公有云终端用户支出将增长18% ;EMNLP 2020最佳论文:无声语音的数字发声
!(https://static001.geekbang.org/infoq/af/af9f6637b50b09be60b00a42f3812d5e.png)开发者社区技术周刊又和大家见面
京东小程序平台助力快送实现跨端 | 京东云技术团队
前言:京东小程序开放平台是由京东自主研发的开发者开放平台,类似于微信和支付宝的小程序开放平台,提供了丰富的开放能力和完整的小程序开发生命周期所需的功能。开发者可以轻松地使用开发者工具IDE进行开发、调试、预览和代码转换,并在控制台进行线上小程序发布、审核、
算法蝉翼
算法蝉翼
Lv1
如果一开始就不了解,就自然而然的没有了以后。
文章
4
粉丝
0
获赞
0