微信小程序在页面,自定义组件中使用数据监听器
发表时间:2021-1-5
发布人:葵宇科技
浏览次数:162
数据监听器可以用于监听和响应任何属性和数据字段的变化,通常会在监听到某个值的改变时去操作data中的其它属性值。
在自定义组件中使用监听器:Component({
properties:{//监测传过来的属性
num: {
type: String,
observer: function(newVal, oldVal) {
console.log('properties-num', newVal)
}
},
person: {
type: Object,
observer: function(newVal, oldVal) {
// console.log('properties-person', newVal)
}
}
},
data: {
aloneVal: 0,
oneVal: null,
twoVal: null
},
observers: {//能够监测到props和data中的
// 监听全部 setData,每次 setData 都触发,一般用不到 '**' 监听全部
'**':function (val) {
console.log('**所有的setData变化:', val) // 此时返回的 val 值是一个包含所有data变量的对象
},
// 监听 properties 接收的值的变化
'num' (val) {
console.log('observers-num', val)
},
// 监听对象
'person' (val) {
console.log('observers-person', val)
},
// 监听对象的属性
'person.name' (val) {
console.log('observers-person.name', val)
},
// 监听子组件中单个数据的变化
'aloneVal' (val) {
console.log('aloneVal', val)
},
// 监听子组件中多个数据的变化
'oneVal, twoVal' (val1, val2) {
console.log('oneVal', val1)
console.log('twoVal', val2)
}
},
// 在组件在视图层布局完成后执行
ready() {
setInterval(()=>{
this.setData({
aloneVal:this.aloneVal+1
})
},1000)
},
})
实现自定义组件的计算属性computed功能需要利用自定义组件扩展behavior.js
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/extend.html
新建一个behavior.js文件
// behavior.js
module.exports = Behavior({
lifetimes: {
created() {
this._originalSetData = http://www.wxapp-union.com/this.setData // 原始 setData
this.setData = this._setData // 封装后的 setData
}
},
definitionFilter(defFields) {
const computed = defFields.computed || {}
const computedKeys = Object.keys(computed)
const computedCache = {}
// 计算 computed
const calcComputed = (scope, insertToData) => {
const needUpdate = {}
const data = defFields.data = defFields.data || {}
for (let key of computedKeys) {
const value = computed[key].call(scope) // 计算新值
if (computedCache[key] !== value) needUpdate[key] = computedCache[key] = value
if (insertToData) data[key] = needUpdate[key] // 直接插入到 data 中,初始化时才需要的操作
}
return needUpdate
}
// 重写 setData 方法
defFields.methods = defFields.methods || {}
defFields.methods._setData = function (data, callback) {
const originalSetData = this._originalSetData // 原始 setData
originalSetData.call(this, data, callback) // 做 data 的 setData
const needUpdate = calcComputed(this) // 计算 computed
originalSetData.call(this, needUpdate) // 做 computed 的 setData
}
// 初始化 computed
calcComputed(defFields, true) // 计算 computed
}
})
在组件中使用:
const beh = require('./behavior.js')
Component({
behaviors: [beh],
data: {
a: 0,
},
computed: {
b() {
return this.data.a + 100
},
},
methods: {
onTap() {
this.setData({
a: ++this.data.a,
})
}
}
})
在页面中使用数据监测:
1,在app.js中添加以下代码:
//app.js
App({
setWatcher(page) {
let data = http://www.wxapp-union.com/page.data; // 获取page 页面data
let watch = page.watch;
for(let i in watch){
let key = i.split('.'); // 将watch中的属性以'.'切分成数组
let nowData = http://www.wxapp-union.com/data; // 将data赋值给nowData
let lastKey = key[key.length - 1];
let watchFun = watch[i].handler || watch[i]; // 兼容带handler和不带handler的两种写法
let deep = watch[i].deep; // 若未设置deep,则为undefine
this.observe(nowData, lastKey, watchFun, deep, page); // 监听nowData对象的lastKey
}
},
observe(obj, key, watchFun, deep, page) {
let val = obj[key];
// 判断deep是true 且 val不能为空 且 typeof val==='object'(数组内数值变化也需要深度监听)
if (deep && val != null && typeof val === 'object') {
for(let i in val){
this.observe(val, i, watchFun, deep, page); // 递归调用监听函数
}
}
let that = this;
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set: function (value) {
// 用page对象调用,改变函数内this指向,以便this.data访问data内的属性值
watchFun.call(page, value, val); // value是新值,val是旧值
val = value;
if (deep) { // 若是深度监听,重新监听该对象,以便监听其属性。
that.observe(obj, key, watchFun, deep, page);
}
},
get: function () {
return val;
}
})
}
})
2,在页面index.js中使用:
// pages/index/index.js
import initComputed from '../../lib/wxComputed.min.js'// 引入computed属性方法
const app = getApp()
Page({
data:{
createProcesDescribe:'',
createProcesName: '',
lastName: 'aa',
firstName: 'bb',
},
onLoad(option){//监听页面加载
app.setWatcher(this)// 设置监听器,建议在onload里设置
initComputed(this)//执行computed属性初始化
},
// computed属性
computed: {
// 这是一个函数,返回值为此计算属性的值
fullName() {
return this.data.lastName + '-' + this.data.firstName
},
},
//watch监听data里的数据
watch:{
createProcesName:{
handler(newVal,oldVal){
console.log(newVal,oldVal)
}
},
createProcesDescribe:{
handler(newVal,oldVal){
console.log(newVal,oldVal)
},
},
})
总结:在自定义组件中直接使用observers其实跟Vue框架中使用watch作用一样,如果在自定义组件中使用computed属性功能则需要引入组件扩展。在页面中使用watch也需要自己在外部添加监听方法,然后在需要监听的页面中引入监听器,并设置监听器,如果在页面中需要使用j计算属性computed也需要在页面中引入该功能文件。