使用selectComponent可以抓取自定义组件实例对象,但在层层嵌套结构的业务场景中,id的设置繁复,js/wxml开发界面频繁的切换,查找、维护、调整的开发工作很是让人抓狂啊
好想封装一个getElementsById方法给小程序,像在web开发中那样能够方便的获取页面元素。在父子子子子级间轻松调用,好想念jquery开发的一把梭时代!
实现如下需求:
- 任何绑定id的自定义组件都能够方便抓取实例对象(任何嵌套层级均可调用)
- 通过数据配置
思路
实现不难,我们可以将所有自定义组件在create生命周期方法时将this
挂载到一个全局变量中,detached
生命周期时销毁该实例(不然爆内存)
实现
准备一个全局变量
app._elements = {}
挂载/销毁方法
一个全局的挂载、销毁方法,方便将实例对象注册、注销在app._elements上
app.mount = function(id, context){
app._elements[id] = context
}
app.unmount = function(id){
app._elements[id] = null
}
getElementsById
定义全局getElementsById
在Page中能够方便调用
app.getElementsById = function(id){
let res = app._elements[id]
if (!res) { // 兼容selectComponent
return wx.selectComponent('#'+id) || wx.selectComponent('.'+id)
}
return res
}
自定义组件
ui-component组件
const app = getApp()
Component({
options: {
multipleSlots: true, // 在组件定义时的选项中启用多slot支持
addGlobalClass: true
},
properties: {
dataSource: {
type: Object,
},
},
data: {},
behaviors: [],
lifetimes: {
created: function() {
},
attached: function() {
this.id = this.data.dataSource.$$id // 专用$$id来指定唯一名称
},
ready: function() {
app.mount(this.id, this)
},
detached: function(){
app.unmount(this.id)
}
},
methods: {
active(clsName){
/* do something */
}
})
应用
下面开始在Page中使用getElementsById
来抓取自定义组件实例
wxml
<ui-component dataSource="{{config}}" />
js
Page({
data: {
config: {
$$id: 'component-id',
title: 'some text'
}
},
onReady(){
// 我们应该在onReady中来调用,onLoad时,页面组件结构并没有渲染完成
const $ele = app.getElementsById('component-id')
$ele.active('.active')
}
})
至此,基本思路已经实现,现在即兼容了selectComponent方法,又简化了写模板id的麻烦。不知道大家有没有了解小程序组件是可以递归嵌套自己的(模板不能递归嵌套)。因此聪明的你应该可以想到通过数据嵌套去实现组件嵌套,进而实现结构嵌套,这样我们就能够实现很复杂的页面结构,当然小程序目前建议是结构应该在30层左右,然并卵,反正它能够正常显示,哈哈
github地址:https://github.com/webkixi/aotoo-xquery
小程序demo演示