在中主要总结了如何扩展小程序中的Page与Component函数,在开发过程中减少包的引入,这一篇则深入总结小程序自定义组件Component函数还有哪些可以进一步扩展的地方【】。
优化点:
- 优化组件定义默认值时声明的写法
- 自定义watch函数监听全部参数变化
编写小程序自定义组件时 你是否是这样?
Component({ properties: { num: { type: Number, value: 2 }, name: { type: String, value: "abcdef..." }, test: Object // 即使没有默认值也要写上数据类型 }, methods: { //... }})复制代码
Component({ props: { num: 2, name: 'abcdef...', test: {} }, methods: { //... }})复制代码
开始改造properties:
既然我们已经可以重写Component函数了,那就有办法把这个数据【转换】成我们要的那种结构格式,打开 Component函数部分
实现的步骤大概是:取到参数内名为props的对象 -> 获取每一个数据类型 -> 还原成小程序原来的数据格式 -> 重新赋值给properties
// 优化 properties 传入方式let originComponent = Component;Component = (opt) => { let { props = {} } = opt; let properties = {}; // 获取自定义关键字【props】中的每一项 Object.keys(props).forEach(item => { // 重新还原成原有数据格式 properties[item] = { type: getValueType(props[item]), // 获取数据格式 value: props[item] } }); opt.properties = properties; // 还给properties... //... return originComponent(opt)}/** * 获取数据类型 * @param value * @returns {*} */function getValueType(value) { if (typeof value === 'number') return Number; if (typeof value === 'string') return String; if (typeof value === 'boolean') return Boolean; if (value instanceof Object && !value instanceof Array) return Object; if (value instanceof Array) return Array; return null;}复制代码
组件声明默认数据格式的修改就弄好了,其实这个东西并没有对开发上起到多么明显的优化,无非就是少写几个字而已,但是以此demo 还可以扩展出更多功能。
监听组件传入参数变化
小程序自定义组件的传入数据上可以声明observer监听器属性,用来监听数据变化⤵️
Component({ properties: { num: { type: Number, value: 2, observer (newVal, oldVal, changedPath) { //... } }, }, methods: { //... }})复制代码
其中observer接收的参数分别是newVal[改变的参数]、oldVal[改变之前的参数]、changedPath[具体改变的参数的key]
默认要监听某个参数的时候,都是需要写在具体参数的对象内的,并且每个要监听的数据都要声明observer函数,通过改造后 可以统一监听数据变动⤵️
Component({ props: { num: 2, name: 'abcdefg....', }, methods: { // 自定义添加的监听方法 $watch(newVal, oldVal, changedPath) { if (changedPath == 'num' && newVal == 5) { this.data.name = 'five'; return this.triggerEvent("isFive") } //... } }})复制代码
相比每个参数都要监听 这种写法可以减少代码。
实现$watch:
实现步骤:获取自定义props对象 -> 还原成properties格式 -> 每一个数据内都添加observer函数 -> 函数在触发时 调用自身$watch函数
// 优化 properties 传入方式let originComponent = Component;Component = (opt) => { let { props = {} } = opt; let properties = {}; // 获取自定义关键字【props】中的每一项 Object.keys(props).forEach(item => { // 重新还原成原有数据格式 properties[item] = { type: _util.getValueType(props[item]), value: props[item], // 每一个数据都添加observer方法监听 observer: function (newVal, oldVal, changedPath) { const changeEvent = { event: item, newVal, oldVal, changedPath }; // 传入属性可通过组件内定义的$watch方法统一监听变化 this.$watch && this.$watch(changeEvent); } } }); opt.properties = properties; // 还给properties... //... return originComponent(opt)}/** * 获取数据类型 * @param value * @returns {*} */function getValueType(value) { if (typeof value === 'number') return Number; if (typeof value === 'string') return String; if (typeof value === 'boolean') return Boolean; if (value instanceof Object && !value instanceof Array) return Object; if (value instanceof Array) return Array; return null;}复制代码
这样就可以实现$watch方法啦!【】