记在封装组件库时,遇到的样式问题
背景
组件库使用 element-ui 2.13.0
, 最后会将组件样式和element-ui
中使用到的组件的样式, 打包成一个 css 文件.
现象
- 在旧平台(element: 1.3) 引入组件库以及样式
- 可以看到, 组件库中
element-ui 2.13.0
的checkbox
样式, 影响了旧平台中的checkbox
希望达到的效果
让组件库中涉及element-ui
组件的样式, 只作用于组件库中的组件
尝试过的方法
- 方式一: 组件引入
element
组件样式时, 增加scoped
1 | <template> |
problem:
这种方式, 将样式引入写在父组件了, 但 <style scoped>
仅仅会影响到当前组件, 会为当前组件的 dom 节点增加data-v-xxx
属性, 并为所有 css 样式增加 [data-v-xxx]
属性选择器, 如下图:
- 方式二: 组件库在编写组件时, 最外层增加
namespace
1 | <template> |
problem:
当遇到会插入到 body
的组件(例如弹出框 el-popover
)时, 命名空间不生效
- 方式三 : scoped + deep
1 | <template> |
problem:
该方法本质上会生成: [data-v-xxx] .el-checkbox {},
相当于 [data-v-xxx]
为命名空间[Emm] 对于 el-datepicker
等生成弹出框并插入body
的组件同样不生效, el-select
可以将弹出框限制不插入body
, 而 el-datepicker 不行. 需梳理哪一些组件提供了 append-to-body 的 props
append-to-body prop
针对方式三, 只要将弹出框限制不插入到 body 即可
只要在源码中引入了 El-popover 或者 element-ui/src/utils/vue-popover mixin 的组件均包含 append-to-body
有一些组件虽然支持 append-to-body = false, 但是并没有在官方文档中体现 , 不排除会有问题出现, 或者
升级之后 append-to-body 可能被去除(固定 element 版本即可)
相关的组件以及插入到 body 的 prop:
popper-append-to-body:
- el-select
- el-autocomplete
append-to-body:
- el-cascader
- el-datepicker
- el-popover
- el-color-picker (! not work) ****
- el-drawer
- el-dropdown (!需要加在子级 el-dropdown-menu, 但展示有问题, 需设置 style="width:max-content")
- el-timepicker
- el-tooltip
- el-dialog (默认 false)
model-append-to-body:
- el-dialog
Other problems
- 组件内部的 show-tooltip ?
解决方法: tooltip 样式设置为全局 ok, 因为 element1.4 与 2.13 样式是相同的
- element 组件内部引用了其他组件, 例如 el-pagination 内使用了 el-select, 无法修改 append-to-body ?
解决方法: 增加自定义类名, 并手动设置 dropdown 样式
1 | <Pagination popper-class="custom-popper"/> |
- $message / $confirm / $notification ?
解决方法: 不使用该类提示, 抛出事件, 由外部处理.
- 第三方库样式 ?
解决方法: 增加命名空间即可.
- 组件引入顺序引起的样式冲突, 如 select 中的 scroll__wrap, 如果 select 放在 cascader 后引入, 会影响 cascader 的样式
解决方法: 目前发现 cascader 会受影响, 将 cascader 放在最后引入
- dart-sass 打包的字体乱码?
解决方法: 换成 node-sass ✔️, 在 vue-cli 增加以下配置:
1 | // npm i node-sass -D |
- 打包后@font-face 样式有问题, 会变成,
::v-deep
没有成功解析 :
1 | @font-face{ |
暂用正则替换 ::v-deep
解决: packages/admin-ui/build/fix-deep.js