发现并面对 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 伪元素的 content 是 乱码。why?
刷新一下「问题控台」试试:
刷新后图标正常显示了,但是伪元素的 content 怎么有点看不懂呢?
试试另一个「正常控台」:
这里的 content 正常。咦!为什么 el-icon 元素 css 样式在 chunk-elementUI.68c70ad5.css 文件里,而之前出问题的控台 el-icon 元素 css 样式在 app.ca199f0d.css 里。难道是打包的锅? 对比一下两个项目的 vue.config.js ,关于 elementUI 的打包没有差异呀!
第二步:本地运行「问题控台」,定位问题
找一个 el-icon 元素,查看元素 style:
点击右侧 ,跳转到对应的 css 样式文件:
这是什么??让我来项目源代码,全局搜索 I think ElementUI
一下:
哈哈,罪魁祸首难道就是你?
element-variable.scss
文件是 vue-element-adamin
模板中用于 "在项目中改变SCSS变量 "。vue-element-adamin
的 main.js
和 store/modules/settings.js
都引用了这个文件。
现在尝试把两处的引用注释掉, main.js 改引用默认样式 import 'ElementUI/lib/theme-chalk/index.css'
。页面刷新,检查元素:
?正常了,问题解决了!此处有掌声 ??? !
第三步:对比「问题控台」和「正常控台」
问题控台 | 正常控台 | 模板 | 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 打包好的样式文件,不再重新打包,也就不会出现乱码。
解决办法汇总
- 不去自定义 SCSS 变量,直接使用 ElementUI 打包好的样式文件。【我选的这个】
- 卸载 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文档的图标。
为什么这里 el-icon 伪元素的 content 也是这样?为什么官方文档就没有出现乱码呢?那我上面一通分析个啥?我的解决方法太鸡肋了?呜呜!肯定 Element Plus 做了其他调整,心累!!!!!!!!!
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!