css 是没有父元素选择器的。可是现在有伪选择器
has
,这个可以实现父选择器的愿望。通过 has 这个词,也很容易记住和理解。就像一个反向思维一样,本来需要一个父级,那如果我父级就在那,我判断是否有子集不就通了吗。而 css 从来都是从父到子到兄的。
https://developer.mozilla.org/zh-CN/docs/Web/CSS/:has
为什么要搞这玩意呢。还是因为在使用 element-ui 的上传组件时,当用户选择了一张图片后,上传按钮还是显示在那地方。这样体验很差也不好看。即使你加了 limit:1 的控制也不行。不知道为啥会这样(我没找到对应的 api 还是就是这样呢)。
既然这样了,那总得处理。最直接的一种方式是通过 js + css 的方式。对于 html,只要 js + css 是没有搞不定的。可是这样代码不好看了啊,也增加了多余的逻辑。通过观察组件的 dom 结构,可以发现,不管是否有选择的图片,上传按钮的兄弟级存在一个 li
标签。 只要选择了图片或默认存在的图片,都会存在一个
样式为 .el-upload-list__item
的 div。那好,这个时候就想到,如果存在父选择器,再通过父选择器的兄弟选择,通过 display:none
,不就可以隐藏了吗。
可是,可是就是没有父选择器啊。可是,可是 has 伪选择器就是可以实现这样一个场景就是父选择器。
下边是 element ui 的上传组件的结构(精简模拟的)
# 没选择图片的
<div class="upload-card">
<li></li>
<div class="upload-btn">
</div>
</div>
# 选择图片的
<div class="upload-card">
<li>
<div class="el-upload-list__item"></div>
</li>
<div class="upload-btn">
</div>
</div>
通过 has 就可以实现隐藏了。
.upload-card:has(.el-upload-list__item) .upload-btn {
display:none;
}
```
### 真实 code
```
#template
<el-form-item label="封面" prop="cover">
<el-upload ref="coverUpload" class="upload-card" action="#" :multiple="false" list-type="picture-card" :file-list="image.cover" :http-request="uploadCover" :auto-upload="false">
<i class="el-icon-plus" />
</el-upload>
</el-form-item>
# scss
::v-deep .upload-card:has(.el-upload-list__item) .el-upload--picture-card {
display: none !important;
}