Vue.js 里有 watch 监听机制,很适宜“一处扭转,多处影响”的场景,在开发小程序的过程中,天然也会遇到这样的场景,上面介绍如何在小程序中实现 watch 监听。
1. 定义 watch.js
在根目录(miniprogram
)下创立watch.js
,代码如下:
// watch.js
const observe = (obj, key, watchFun, deep, page) => {let oldVal = obj[key]
// 如果监听对象是 object 类型并且指定 deep(深度监听)if (oldVal !== null && typeof oldVal === 'object' && deep) {// 递归子集,顺次执行 observe()
Object.keys(oldVal).forEach(item => {observe(oldVal, item, watchFun, deep, page)
})
}
// 应用 Object.defineProperty()劫持数据的写操作,在监听对象扭转后执行传入的 watchFun
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set(value) {if (value === oldVal) return
watchFun.call(page, value, oldVal)
oldVal = value
},
get() {return oldVal}
})
}
export const setWatcher = (page) => {
// 页面里的 data 字段
const data = page.data
// 页面里的 watch 字段
const watch = page.watch
// 对 watch 里列举的每一个字段(须要监听的字段)执行 observe()
Object.keys(watch).forEach(key => {
let targetData = data
const targetKey = key
// 反对 deep 深度监听,应用 deep 时须要配合 handler 应用,否则间接编写函数
const watchFun = watch[key].handler || watch[key]
const deep = watch[key].deep
observe(targetData, targetKey, watchFun, deep, page)
})
}
2. 应用办法
在须要应用监听机制页面的 js 文件(如 index.js)onLoad
钩子里,执行 setWatch
(应用import
关键词从 watch.js
引入),并传入以后页面实例this
,实现初始化。
增加 watch 对象,外部写入须要被监听的字段以及执行函数:
// index.js
import {setWatch} from '../../watch.js'
Page({data: { ...},
watch: {
// 须要监听的字段
foo(val) {console.log('foo 变动了,变动后的值是', val)
... // 具体操作
}
},
// watch 初始化,传入以后页面实例 this
onLoad() {setWatch(this)
}
})