为什么 vue 中的 scoped 样式没用?父元素样式仍然影响子元素

Jac*_*len 5 javascript css vue.js

父元素样式:

.container {
margin: 20px;
border:1px solid #f1f1f1;
font-size:14px;
font-weight:normal;
Run Code Online (Sandbox Code Playgroud)

子元素样式:

.container{}
Run Code Online (Sandbox Code Playgroud)

但是子元素样式应该像这样呈现:

在此处输入图片说明

为什么data-v-***子元素中有两个并使用父容器样式?

Ste*_*ton 5

我知道已经很久了,但我要在这里添加一些东西来帮助未来的人。

我遇到了同样的事情。基本上,我在组件中嵌套组件,并且非常喜欢scoped这样每个组件都有一个名为.container...的类,当渲染样式开始发生冲突时,这让我感到惊讶。我以为scoped是为了解决这个问题......

但显然按照设计,情况并非如此:

https://vue-loader.vuejs.org/guide/scoped-css.html#mixing-local-and-global-styles

使用 scoped,父组件的样式不会泄漏到子组件中。但是,子组件的根节点将同时受到父级 CSS 和子级 CSS 的影响。这是设计使然,以便父元素可以为布局目的设置子根元素的样式。

例如,我嵌套了两个组件,我最终得到了这个:

在此处输入图片说明

我在两个组件中有一个视图加载:

<template>
  <div>
    <login-splash />
    <login-form />
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

包括的两个是这样的:

<template>
  <div class="container">
    <div>
      <h1 class="big">Title</h1>
      <h2 class="small">Subtitle</h2>
    </div>
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)
<template>
  <div class="container">
    <form class="form">
      <label class="label">Username
        <input class="input" type="input" name="username">
      </label>
      <label class="label">Password
        <input class="input" type="password" name="password">
      </label>
      <a href="" class="link">Forgot Password</a>
    </form>
    <button-submit />
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

问题是button-submit它看起来像这样:

<template>
  <div class="container">
    <button class="button">Button</button>
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

这些文件中的每一个都有scopedSCSS,最终会产生上述问题。

这一切都回到了https://vuejs.org/v2/style-guide/#Component-style-scoping-essential

基本上解决方案是“使用像 bem 这样的基于类命名的解决方案”......这不是任何人在看到和使用scoped并认为这是一个灵丹妙药时都想听到的......我知道......但就像所有网络一样发展,你必须做你必须做的。

如果您正在开发一个大型项目,与其他开发人员合作,或者有时包含 3rd-party HTML/CSS(例如来自 Auth0),则一致的范围将确保您的样式仅适用于它们适用的组件。

除了 scoped 属性之外,使用唯一的类名有助于确保第 3 方 CSS 不适用于您自己的 HTML。例如,许多项目使用按钮、btn 或图标类名称,因此即使不使用 BEM 等策略,添加特定于应用程序和/或特定于组件的前缀(例如 ButtonClose-icon)也可以提供一些保护。


另一种方法是使用 CSS 模块,如本答案所述:https : //stackoverflow.com/a/45900067/1034494

这最终会产生这样的东西: 在此处输入图片说明


her*_*off 0

data-v因为您在子组件样式中指定了 CSS 选择器,所以有两个属性。它是空的这一事实并没有改变这一点。只要您不限制两个组件的样式,它们当然就会相互影响,特别是如果您选择相同的类名。