Vue.js CSS 包优先级 (?)

Posted

技术标签:

【中文标题】Vue.js CSS 包优先级 (?)【英文标题】:Vue.js CSS bundle precedence (?) 【发布时间】:2019-05-25 01:38:30 【问题描述】:

我在 Vue.js CLI 生产捆绑中遇到了一个奇怪的问题,我无法确定根本原因,感谢一些帮助。

我的 main.js 中有一个带有以下(相关摘录)的 Vue CLI 3 应用程序:

// Bootstrap
import "@/assets/bootstrap/bootstrap.scss";
import "bootstrap-vue/dist/bootstrap-vue.css";
import BootstrapVue from "bootstrap-vue";
Vue.use(BootstrapVue);

// Toastr
import Toastr from "vue-toastr";
import "vue-toastr/dist/vue-toastr.css";
Vue.use(Toastr, 
  defaultPosition: "toast-bottom-right"
);

在我的开发环境中运行它 (npm run serve) CSS 工作正常。

当我在生产编译 (npm run build) 之后运行此程序时,某些类...未应用,我无法解释原因。鉴于我能看到的唯一区别是捆绑过程,我倾向于在这个方向寻找问题。

我在我的 vue.config.js 中按如下方式定制了捆绑(相关摘录):

cacheGroups: 
  icons: 
    name: "icons",
    test: /[\\/]node_modules[\\/](@fortawesome)[\\/]/,
    chunks: "all",
    priority: 3
  ,
  vendors: 
     name: "vendors",
     test: /[\\/]node_modules[\\/]/,
     chunks: "all",
     priority: 1
  

因此,我捆绑的 CSS 正确创建如下:

一个包含 Toaster CSS 的 vendor 块。 这包括一个“toaster”类和一个“toaster-info”类(最新的只有一个背景色) 一个 应用程序 缝隙,其中包括我自定义构建的引导 CSS。 尽管引导文件位于 node_modules 文件夹中,因此它们应该放在上一个缝隙中,它们进入这里是因为我正在将它们编译为上面的 SASS 文件中的导入,该文件实际上来自代码。 这又包括一个“烤面包机”课程。

现在,我能看到的是:

这两个块似乎都是由浏览器加载的 标记正确使用了“toastr toastr-info” 仅应用来自应用程序(引导程序)的“烤面包机”类 'toaster' 和 'toaster-info' 类被浏览器完全忽略,'toaster-info' 的背景颜色也未应用

我用几种浏览器对此进行了测试,以排除任何特定的浏览器异常。 浏览器计算的样式显示,由于某种我不明白的原因,这些类被“排除”了(“排除”的含义在样式树中,但有删除线)。

谁能帮我理解为什么会这样?

谢谢。

【问题讨论】:

在您的开发控制台中,在检查元素时,您可以使用 "Computed" 选项卡来查看应用了哪些样式以及它们的位置已定义。 是的,这就是我上面所说的“浏览器调试”。课程显示为“删除线”,但我不知道为什么。 能否请您从浏览器控制台发布一些屏幕截图?如果样式被覆盖(通常是什么导致它们被显示),您需要找到 正在应用 代替 当然,这是我能看到的:capture 对,就是说因为.toast的特异性比其他的更高,所以它是被应用的那个。它可能更高,因为app.css 是在vendor.css 之后定义的。你为什么在你的应用风格中定义.toast 【参考方案1】:

这纯粹是一个 CSS 问题。

由于您的应用和供应商 CSS 定义了 .toast 类样式,因此最后加载的内容具有最高的特异性。

我假设您要做的只是将默认的 .toast 背景颜色更改为白色(而不是黑色),但您想保留更具体的类,如 .toast-info.toast-success 等他们是。

为此(不更改供应商文件),您可以将 .toast 定义更改为...

.toast:not(.toast-info),
.toast:not(.toast-success),
.toast:not(.toast-warning),
.toast:not(.toast-error) 
  background-color: rgba(255, 255, 255, .85);

如果你使用的是 Sass 之类的预处理器(我认为你是这样的),这可以写得更简洁。


理想情况下,供应商文件应该已经定义了它们的样式,例如...

.toast 
  background-color: #030303;

.toast.toast-success 
  background-color: #51a351;

这将使“info”“success” 等样式比 .toast 类具有更高的特异性,但看起来不像。也许你可以创建一个拉取请求?

【讨论】:

我了解优先级。实际上,这两个类都来自供应商文件,因此我无法更改它们(尽管我并没有真正使用引导程序中的那个)。我仍然不明白这一点:toast-success 是在没有链接 .toast-success background-color: #something 的情况下定义的 - 背景颜色是否会被丢弃,因为在优先级(你看到的那个白色)中定义了背景颜色? @Edoardo .toast.toast-success 都具有相同的优先级/特异性,并且都分配给您的 html 元素,因此无论哪个定义 background-color 最后一个都是获胜的。这就是为什么我添加了关于供应商文件应该理想做什么的注释。 @Edoardo 我假设白色的.toast 是在@/assets/bootstrap/bootstrap.scss 中定义的,因为它出现在您的 app 块中而不是 vendor 块中.如果不是,则必须在您的应用文件中的其他位置进行定义。 首先,感谢您花时间回答我。你是对的,白色来自那里。问题是烤面包机 CSS 进入了 vendor 包,因为它是直接从 node_modules 导入的。 Bootstrap,理想情况下也应该到达那里,但由于导入 SCSS 在我的代码中,进入“应用程序”包,稍后加载并取消优先级。 我找到了一种将两个捆绑包的内容重定向到一个的方法。现在同一个类的两个定义(和toast-success)都在同一个文件中......无论它们的构建顺序如何,它仍然不起作用。

以上是关于Vue.js CSS 包优先级 (?)的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 从源码理解v-for和v-if的优先级的高低

vue.js基础知识篇:与服务端通信

Vue.js源码全方位深入解析 (含Vue3.0源码分析)

vue2.0生命周期详解(前端网备份)

Vue.js CLI 3 - 如何为 CSS/Sass 创建供应商包?

css的优先级顺序是怎样的