在上一篇watch详解中解释了watch 的原理 链接
这次是我抽空完整封装好的demo
效果:
页面中代码写法:
函数触发前:
函数触发后:
具体效果描述:写法与vue中的写法相同,个人做了单向绑定,修改被监听的参数,会同步到视图层
如何使用
1.在项目文件目录下创建一个存储外部脚本的文件夹 例:single
2.创建一个js文件,并且写入以下代码 例:watch.js
写入代码
let singlever = {
watch(_this,state) {
if (!_this) { throw 'page对象不存在' }
let subsitute = {}
let watchFunc = _this.watch
if(watchFunc.constructor === Function){ //非page构造
console.info('非Page页面,使用组件加载模式')
watchFunc = _this.watch()
}
Object.keys(watchFunc).some(item => {
//创建缓存监听get初始化数据
subsitute[item] = _this.data[item]
if(watchFunc[item].constructor === Object){
console.log('数据为object')
Object.defineProperty(_this.data, item, {
set: function (val) {
if (subsitute[item] === val) { return }
subsitute[item] = val
watchFunc[item].set(val,_this)
},
get:watchFunc[item].get(_this)
})
}else{
Object.defineProperty(_this.data, item, {
set: function (val) {
if (subsitute[item] === val) { return }
subsitute[item] = val
watchFunc[item](val,_this)
},
get(){
return subsitute[item]
}
})
}
})
}
}
module.exports = singlever
3.在小程序入口js文件 app.js 文件中引入
4.对其进行封装
5.封装完毕后,可对其进行调用,因为不同类型的页面构造函数不一样,所以引入的写法不一样,
(所有的页面都要先通过getApp函数获取的App对象再调用其封装的方法)
正常的Page中:
推荐在onLoad中调用
onLoad: function (options) {
const app = getApp()
app.watch(this)
},
完整的写法 在Page构造的页面中watch的写法和vue一样,与data同级
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
aaa: 123
},
watch:{
aaa(val){
console.log('page函数',val)
}
},
onLoad: function (options) {
app.watch(this)
},
onShow: function () {
},
})
组件Component中写法:
推荐在ready中调用
ready(){ //类似于beforeMounted 组件挂载前
const app = getApp()
app.watch(this)
},
完整的写法 在Component构造的组件页面中,需要将 watch 以函数的形式写入到 methods 中,并且用return返回
const app = getApp();
Component({
data:{
lll:123,
},
methods: {
watch(){
return{
lll(val){
console.log('lll改变成功')
}
}
},
},
ready(){ //类似于beforeMounted 组件挂载前
app.watch(this)
},
})
//2020 6 .2 更新
修复了页面 watch 对象中,没有 this 指向当前页面的 bug,
当前页面对象 在被监听函数的第二个参数传入 例如:
watch:{
date(val,_this){
console.log(_this)
}
},
输出当前页面对象
最关键可以使用 _this.setData({}) 将未被监听的数据,同步到视图层
//2020 6 11更新
在 Component 组件中,监听之后的数据将无法使用 this.data.xxx 来读取到该数据
暂无解决方法 ,组件中慎用监听
//2021 7.19更新(undefined问题解决)
问题在于使用 defineProperty 重构对象属性的get,set之后,get方法默认会返回undefined,所以导致之前可以正常修改属性,触发set,但获取值的时候为undefined
重新正确构写get之后监听使用正常