「今日份BUG」ElementUI 图标乱码

发现并面对 BUG

最近写PC端控台项目,模板用的是 vue-element-adamin。遇到一个问题:项目部署到线上,偶尔会出现 ElementUI 图标显示乱码,刷新一下又好了,本地未出现该情况。

问题项目模板和相关依赖的版本信息
vue-element-adamin 4.4.0
element-ui 2.13.2
sass 1.26.8
sass-loader 8.0.2
复制代码

之前以为是字体图标文件加载问题,加上工作繁忙 ?,就没管它。今天做另一个控台项目,突然想起这事儿,为什么这个控台项目就没出现这个问题呢? 看来这是个 BUG 呀,得找原因!

着手解决 BUG

先网上寻求帮助

先 google/baidu 一下,大部分的解释都是 ElementUI 使用的是 node-sass, 你的项目中使用 dart-sass 就会出现这个问题。

解决方案:卸载 sass 装 node-sass 即可。

可是Sass 官方都弃用了 node-sass ,推荐使用 sass (dart-sass) 。为啥我们还要换回去呢?有没有别的解决方案呢?

还是得靠自己

对比了手上的两个控台项目,都是用的 dart-sass 呀? 为什么一个有问题,一个没有问题呢?看来另有隐情。不想用过时的 node-sass,咋办呢?

第一步:看看各种状态下图标元素到底渲染的啥?

打开「问题控台」,咦!刚好,icon 又乱码了。右键检查元素,查看结果如下:

icon-乱码.png

咦!这个 icon 伪元素的 content 是 乱码。why?

刷新一下「问题控台」试试:

icon-刷新好了.png

刷新后图标正常显示了,但是伪元素的 content 怎么有点看不懂呢?

试试另一个「正常控台」:

另一个控台.png

这里的 content 正常。咦!为什么 el-icon 元素 css 样式在 chunk-elementUI.68c70ad5.css 文件里,而之前出问题的控台 el-icon 元素 css 样式在 app.ca199f0d.css 里。难道是打包的锅? 对比一下两个项目的 vue.config.js ,关于 elementUI 的打包没有差异呀!

why.jpeg

第二步:本地运行「问题控台」,定位问题

找一个 el-icon 元素,查看元素 style:

icon-style.png

点击右侧 ,跳转到对应的 css 样式文件:

icon-style2.png

这是什么??让我来项目源代码,全局搜索 I think ElementUI 一下:

icon-style3.png

哈哈,罪魁祸首难道就是你?

element-variable.scss文件是 vue-element-adamin 模板中用于 “在项目中改变SCSS变量 “。vue-element-adaminmain.jsstore/modules/settings.js 都引用了这个文件。

现在尝试把两处的引用注释掉, main.js 改引用默认样式 import 'ElementUI/lib/theme-chalk/index.css'。页面刷新,检查元素:

icon-正常了.png

?正常了,问题解决了!此处有掌声 ??? !

第三步:对比「问题控台」和「正常控台」

问题控台 正常控台
模板 vue-element-adamin vue-adamin-template
是否改变SCSS变量
相关依赖 element-ui 2.13.2
sass 1.26.8
sass-loader 8.0.2
element-ui 2.13.2
sass 1.26.8
sass-loader 8.0.2

两个控台项目主要的差异是模板不同,vue-element-adamin 修改了 ElementUI 默认 SCSS变量,el-icon 相关的样式使用 dart-sass 重新打包到 app.css 文件,打包结果中 el-icon 元素的伪元素 content 属性异常。而vue-adamin-template 未修改默认样式,会直接采用 elementUI 打包好的样式文件,不再重新打包,也就不会出现乱码。

解决办法汇总

  1. 不去自定义 SCSS 变量,直接使用 ElementUI 打包好的样式文件。【我选的这个】
  2. 卸载 sass ,安装 node-sass。

关于 node-sass 和 dart-sass

SASS 官方团队,在2020年10月26号宣布弃用 Libsass (包括基于它构建的 node-sass 点击查看原文) ,转向 dart-sass 。

为什么弃用 libSass, 因为 libSass 底层语言是C/C++,添加新功能变得困难。

Node-sass 存在的问题:npm 下载时间长, 安装时容易出错。目前,node-sass 已停止更新,只持续维护。

其他方面的对比:

node-sass dart-sass
编译主体 用 node(调用 cpp 编写的 libsass) drat VM
编译时机 自动实时编译 保存后
编译速度 比 node-sass 慢点
下载速度 快(被编译为纯js)

Vue 项目,node-sass 和 dart-sass 部分语法不兼容。dart-sass 支持 ::v-deep ,不支持 /deep/ 。

.foo /deep/ .bar { width: 100px; }
// 使用 dart-sass 需改为
.foo ::v-deep .b { width: 100px; }
复制代码

说到深度选择器,vue 官方 rfc 给出新的写法。

<style scoped>
/* DEPRECATED  >>> 和 /deep/ 也废弃了 */
::v-deep .bar {}
  
/* deep selectors */
::v-deep(.foo) {}

/* targeting slot content 子组件内修改 slot 样式 */
::v-slotted(.foo) {}

/* one-off global rule  全局范围 */
::v-global(.foo) {}
</style>
复制代码

彩蛋

基于Vue 3 的Element Plus 使用的是 dart-sass!等等,我来看下Element Plus文档的图标。

image.png

为什么这里 el-icon 伪元素的 content 也是这样?为什么官方文档就没有出现乱码呢?那我上面一通分析个啥?我的解决方法太鸡肋了?呜呜!肯定 Element Plus 做了其他调整,心累!!!!!!!!!

崩溃.jpeg

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享