vue 如果有某个子元素就给父元素加样式,或者通过子元素显示来判断父元素是否显示

有这样一个场景,父元素是一个 div,然后里边有多个子元素,同时父元素上添加了很多样式
需求是:如果有子元素,那么就显示父元素,如果没有一个子元素,则父元素也不显示

代码结构:

<div class="more-css">
	<aaa v-if="isaaa" />
	<bbb v-if="isbbb" />
	<ccc v-if="isccc" />
	<ddd v-if="isddd" />
	<eee v-if="iseee" />
</div>

第一种做法

可以在父div上,加一个v-if,但是要把子元素所有的判断都列出来,如
<div class="more-css" v-if="isaaa || isbbb || isccc || isddd || iseee"></div>
元素少,判断少还好,否则,简直是噩梦

第二种做法

利用css的:has伪类

<div class="more-css check-show">
	<aaa class="child" v-if="isaaa" />
	<bbb class="child" v-if="isbbb" />
	<ccc class="child" v-if="isccc" />
	<ddd class="child" v-if="isddd" />
	<eee class="child" v-if="iseee" />
</div>

//css
.check-show {
	display: none;
}
.check-show:has(.child) {
	display: block;
}

首先利用check-show这个class把父元素 隐藏,然后.check-show:has(.child)此样式可以校验如果有子元素,再把父元素显示出来即可;
但是此方案有个缺点,就是has伪类的浏览器兼容比较差,ie全军覆没,无法使用

最终方案:

利用自定义指令:

<div class="more-css" v-show="isShow.num">
	<aaa v-child={data: isShow} class="child" v-if="isaaa" />
	<bbb v-child={data: isShow} class="child" v-if="isbbb" />
	<ccc v-child={data: isShow} class="child" v-if="isccc" />
	<ddd v-child={data: isShow} class="child" v-if="isddd" />
	<eee v-child={data: isShow} class="child" v-if="iseee" />
</div>

//js
data() {
	return {
		isShow: {num: 0}
	}
},
directives: {
	child: {
		//被绑定元素插入父节点时调用
		inserted(_, binging) {
			binging.value.data.num++;
		},
		//只调用一次,指令与元素解绑时调用
		unbind(_, binging) {
			binging.value.data.num--;
		},
	}
}

此方法利用自定义指令在子元素插入父节点时触发,此时说明子元素已经通过校验显示出来了,那么就给传入的变量 ++,当子元素被移除时,触发unbind钩子,把传入数据 –,父元素只需要判断当前num的数量再显示即可。