回复 刷新

暂无评论

微信小程序在页面,自定义组件中使用数据监听器

数据监听器可以用于监听和响应任何属性和数据字段的变化,通常会在监听到某个值的改变时去操作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 = 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 = page.data; // 获取page 页面data let watch = page.watch; for(let i in watch){ let key = i.split('.'); // 将watch中的属性以'.'切分成数组 let nowData = 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也需要在页面中引入该功能文件。

  • 181
  • 0
  • 0