1. 定义watch.js

  1. // watch.js
  2. const observe = (obj, key, watchFun, deep, page) => {
  3. let oldVal = obj[key]
  4. // 如果监听对象是object类型并且指定deep(深度监听)
  5. if (oldVal !== null && typeof oldVal === 'object' && deep) {
  6. // 递归子集,依次执行observe()
  7. Object.keys(oldVal).forEach(item => {
  8. observe(oldVal, item, watchFun, deep, page)
  9. })
  10. }
  11. // 使用Object.defineProperty()劫持数据的写操作,在监听对象改变后执行传入的watchFun
  12. Object.defineProperty(obj, key, {
  13. configurable: true,
  14. enumerable: true,
  15. set(value) {
  16. if (value === oldVal) return
  17. watchFun.call(page, value, oldVal)
  18. oldVal = value
  19. },
  20. get() {
  21. return oldVal
  22. }
  23. })
  24. }
  25. export const setWatch = (page) => {
  26. // 页面里的data字段
  27. const data = page.data
  28. // 页面里的watch字段
  29. const watch = page.watch
  30. // 对watch里列举的每一个字段(需要监听的字段)执行observe()
  31. Object.keys(watch).forEach(key => {
  32. let targetData = data
  33. const targetKey = key
  34. // 支持deep深度监听,使用deep时需要配合handler使用,否则直接编写函数
  35. const watchFun = watch[key].handler || watch[key]
  36. const deep = watch[key].deep
  37. observe(targetData, targetKey, watchFun, deep, page)
  38. })
  39. }

2. 使用方法

在需要使用监听机制页面的js文件(如index.js)onLoad钩子里,执行setWatch(使用import关键词从watch.js引入),并传入当前页面实例this,完成初始化。
添加watch对象,内部写入需要被监听的字段以及执行函数:

  1. // index.js
  2. import { setWatch } from '../../watch.js'
  3. Page({
  4. data: { ... },
  5. watch: {
  6. // 需要监听的字段
  7. foo(val) {
  8. console.log('foo变化了,变化后的值是', val)
  9. }
  10. },
  11. // watch初始化,传入当前页面实例this
  12. onLoad() {
  13. setWatch(this)
  14. }
  15. })