在小程序中实现 watch
2020/7/19 11:33:35
本文主要是介绍在小程序中实现 watch,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
微信小程序官方没有提供 watch,用来监听 data 中的属性的变化
日常开发中如果少了 watch,会显得束手束脚
ES5 提供了 Object.defineProperty() 的方法,通过 getter/setter 劫持对象,实现在赋值时调用 setter 方法,执行 watch 中对应的方法,从而实现监听。
设置监听者
setWatcher 函数遍历会遍历 data 中的所有属性,给没有一个属性添加一个监听器 observe
const setWatcher = (page) => { const data = page.data const watch = page.watch Object.keys(watch).forEach(key => { let targetData = data const targetKey = key const watchFun = watch[key].handler || watch[key] const deep = watch[key].deep observe(targetData, targetKey, watchFun, deep, page) }) } 复制代码
实现监听器
observe 函数接收 5 个参数
- paga 中的 data
- data 中的属性 key
- watch 中的函数
- 是否要对 data 中的属性进行深度监听
- page,会被传递到监听函数中
如果 deep 为 true 需要深度监听,递归调用 observe,实现深度监听
使用 Object.defineProperty 的 setter 方法拦截外部对 data 数据的处理,同时调用 watchFn 实现监听。
watchFn 接收两个参数,value 和 oldValue,使用 call 将 page 传递进去。使 watch 中可以正常使用 page(this)
/** * * @param {Object} obj // data * @param {String} key // data 属性 * @param {Fucntion} watchFun // 监听函数 * @param {Boolean} deep // 是否深度监听 * @param {Object} page // page */ const observe = (obj, key, watchFn, deep, page) => { let oldVal = obj[key] if (oldVal !== null && typeof oldVal === 'object' && deep) { Object.keys(oldVal).forEach(item => { observe(oldVal, item, watchFun, deep, page) }) } Object.defineProperty(obj, key, { configurable: true, enumerable: true, set(value) { if (value === oldVal) return watchFn.call(page, value, oldVal) oldVal = value }, get() { return oldVal } }) } 复制代码
注意事项:
- watch 只能监听已存在的属性,数组的 pop() 和 push() 等方法不会触发
- 一开始不在 data 中的属性,后续动态添加的属性也不会触发
完整代码
const observe = (obj, key, watchFun, deep, page) => { let oldVal = obj[key] if (oldVal !== null && typeof oldVal === 'object' && deep) { Object.keys(oldVal).forEach(item => { observe(oldVal, item, watchFun, deep, page) }) } Object.defineProperty(obj, key, { configurable: true, enumerable: true, set(value: any) { if (value === oldVal) return watchFun.call(page, value, oldVal) oldVal = value }, get() { return oldVal } }) } export const setWatcher = (page) => { const data = page.data const watch = page.watch Object.keys(watch).forEach(key => { let targetData = data const targetKey = key const watchFun = watch[key].handler || watch[key] const deep = watch[key].deep observe(targetData, targetKey, watchFun, deep, page) }) } 复制代码
使用
import { setWatcher} from "/utils/watch.js" Page({ data: { age: 12, person: { name: 'uccs' } }, onLoad() { setWatcher(this) }, watch: { age(val) { console.log(val) }, person: { deep: true, handler(val) { console.log(val) } } }, onClick() { this.data.age = 18 this.data.person.name = 'tiantian' } }) 复制代码
这篇关于在小程序中实现 watch的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-03-30微信小程序的网络设置,及网络请求:wx.request(OBJECT)
- 2024-01-22基于taro搭建小程序多项目框架
- 2024-01-13小程序开发:在插件市场寻找步骤条组件并二开
- 2024-01-05钉钉小程序生态—企业机器人加互动卡片,改善用户体验的开始!
- 2023-12-29【UniApp】-uni-app-打包成小程序
- 2023-12-26性能翻倍!京东亿级体量小程序优化实践
- 2023-12-25小程序优化:第三方SDK过大解决方案
- 2023-11-26微信小程序文件预览和下载-文件系统
- 2023-11-2652天学习微信小程序计划No.2:注册小程序账号&安装开发者工具
- 2023-11-1952天学习微信小程序计划No.1:小程序简介