1、 如何对父子组件设置flex布局
如果在小程序中对父组件设置 display:flex 或者 display:inline-flex 然后再对子组件最外层元素的class设置flex的样式属性会发现不会有效果。
比如在这个截图中
父元素 .parent-box 是 display:flex 然后对子元素 .child-box 设置 flex、justify-content、align-content 等属性会发现都没有效果。
我们看截图可以发现其实微信小程序渲染完后会对组件里面的内容再套一层组件名称的标签。所以如果要对子元素设置flex属性的话应该对子元素使用小程序提供的:host选择器。
父元素样式
.parent-box{
display:flex;
}
复制代码
子元素样式
:host{
flex: 1;
}
复制代码
2、根据不同条件渲染子组件根节点的样式
比如组件在某些特殊场景不使用flex布局而是采用其他方式布局,我们希望同过某种方式来控制子组件根节点的样式。但是微信小程序的:host选择器似乎没法做到这种需求。如果后面微信小程序的:host选择器可以支持属性选择器也许可以做到。
这里没有找到特别好的办法,这里我说下两种比较差的解决方法
· 在小程序自定义组件标签其实相对于view标签或者text标签可以直接在标签中使用style或者class的。就是利用标签的style或者class动态去改变。
复制代码
这里尝试过在父组件和子组件去设置子组件的class都是没有反应的,所以子组件class只能在Page的Wxss中去设置。
· 一种就是如果明确了子组件的标签名称我们可以在父组件的样式中去设置不同的子组件样式
父元素样式
.parent{
display:flex;
}
.parent-box child{
flex:1;
}
.parent-box.column child{
flex-direction: column;
}
.parent-box.row child{
flex-direction: row;
}
复制代码
不过这种方式也不太好,因为组件的是在Page的json可以随意命名的,这种方法除非是团队开发开始个人约定好了组件的名称,不会随意给组件起名的情况下。
这种方法甚至可以用CSS的选择器控制某一个子组件单独的样式
父元素样式
.parent-box child:first-child{
flex:1;
}
复制代码
父元素获取子元素WMXL
有些时候为了一些组件的扩展性我们会把他们拆成父子组件,又有些时候组件内有一些需要酷炫的样式动画我们可能需要在父组件内拿到子组件的节点信息去进行计算。这里我说下我用的方法。
1、使用 wx.createSelectorQuery().in()
在linked生命周期时会传递过来子组件的实例对象,在这个使用把wx.createSelectorQuery().in传入子组件包装成Promise插入数组。待要获取子元素们的节点信息时调用。
父组件JS
Component({
data: {
childRectPromises:[]
},
relations: {
'/child': {
type: 'child',
linked(v) {
const p = ()=> new Promise((resolve,reject)=>{
const query = wx.createSelectorQuery().in(v)
query.select('.child-box').boundingClientRect(function(res){
resolve(res)
}).exec()
})
this.data.childRectPromises.push(p);
},
}
},
ready(){
Promise.all(this.data.childRectPromises.map(p=>p())).then(res=>{
/* 逻辑 */
})
}
})
复制代码
2、使用 >>> 选择器
如果用上面的方法如果有10个子元素,我们就要调用10次的 wx.createSelectorQuery().in().select()。怎么都感觉十分的消耗性能,如果可以使用selectAll一次性把全部子元素的节点信息给拿到就好了。这时我们就想可以不可以
wx.createSelectorQuery().in(父元素对象).selectAll(子元素节点)
复制代码
经过我的测试,在组件已经渲染完毕有子元素的情况下,返回的是个空数组,说明这种写法是不行的。哪还有什么办法呢。其实在微信小程序中 在selectAll/select中 提供了 >>> 这样一个选择器,这个选择器可以在拿到页面组件中对匹配到的节点。
我们只要 wx.createSelectorQuery().selectAll( 父组件 >>> 子元素节点 ) 像这么写我们就可以一次轻松拿到全部子节点啦。
但是这里我们这么写 wx.createSelectorQuery().selectAll( 父组件元素class >>> 子元素节点 )是没有作用的,我的理解是,因为我们没有在wx.createSelectorQuery()调用in方法就是相当于在Page中查找这些元素,而不是在组件内,父组件元素class是封装在组件内的所以查找不到这个元素,也就返回了空数组。
相对于页面,如果我们用组件的标签名,就如上面所说的组件名可以随意起名并不是很合适,这时我们就想要是知道父组件的某个class或者id就好了,知道父组件设置了什么class可能可能不太显示,不过如果我们对标签设置了id我们确可以从this从获取到。
这时我们成功只用一次selectAll获取到了父组件的子元素们。不过这么做有个缺点就是一定要设置id才行,不过为了性能优化我们可以从在父组件中做个判断如果id为空则提示使用此组件需要设置id。
好了以上就是我在开发小程序中对父子组件的一些心得,如果大家有一些更好的办法或者心得希望可以与我分享,谢谢各位。
赞赏