在VueJS组件中共享通用的CSS

28

我正在进行VueJS 2项目的开发,并尝试清理代码,但在作用域样式上遇到了困难。

这是我的要求。 :)

我有3个非常相似的组件,所以我决定使用mixins将代码合并为一个文件。每个组件都将使用templatevuejsmixins。当我想要自定义特定组件的条件时,可以简单地覆盖其中的代码,在这一部分中它可以正常工作。

然而,我希望做的另一件事是将scoped style也移动到mixins中。目前,样式被包装在<style lang="scss" scoped></style>标签中,在其组件中此样式非常有效,但我必须在所有3个组件中复制样式代码。

我知道可以将这些样式添加到全局css文件中,但我不希望某些样式进入全局范围,只有这3个组件之一会应用这些样式。

是否有任何方法将这些样式添加并应用于mixins?

在此特殊情况下,最佳实践是什么?

4个回答

26

Vue使这变得简单。

解决方案

要在组件中使用共享样式,您可以这样做。

MyComponent.js

<template>
</template>

<script>
</script>

<style lang="scss" scoped>
  @import '@/scss/shared-styles.scss';
  @import 'styles.scss'; // this is the regular CSS used just by the component
</style>

替代方案

您还可以像下面这样在组件CSS文件中导入共享的CSS文件。

MyComponent.js

<template>
</template>

<script>
</script>

<style lang="scss" scoped>
  @import 'styles.scss';
</style>

styles.scss

@import '@/scss/shared-styles.scss'

// rest of your component CSS

自动导入全局样式

如果您想要某些样式在所有组件中都可用,可以这样做。

vue.config.js

module.exports = {
  ...
  css: {
    loaderOptions: {
      sass: {
        prependData: `
          @import "@/scss/global.scss";
        `
      },
    },
  },
}

这应该是被接受的答案.. :) 另外,导入 CSS 文件不可能吗?我必须将其重命名为 .scss 才能在 <style scoped> 标签中工作吗? - Ali Khan
1
嗨 - 是的,这是可能的。只需删除 lang="scss" 属性:<style scoped> - M3RS
当我使用多页应用程序时,这对我不起作用。我正在使用Bootstrap,并且它被导入了多次。 - Brian
1
是的,我认为 scoped 部分不起作用。我 @import 的样式对我来说是全局显示的(这不是我想要的)。 - Clifton Labrum

8
我刚刚发现scoped style也会影响子组件。因此,我找到了解决方案,虽然不确定它是否是最佳实践,但我感觉非常好。
创建一个WrapperComponent,在这里放置scoped style和一个小模板。
<template>
    <div>
        <slot></slot>
    </div>
</template>

<style lang="scss" scoped>
    /* css style that will apply to all children */
</style>

这里发生的情况是,当我们用WrapperComponent包装任何组件时,模板将通过slot传递HTML而不进行任何修改,样式从现在开始就可以应用了。

mixins中,我导入这个包装器并使用WrapperComponent包装组件模板。以下是示例。

import WrapperComponent from './WrapperComponent'

let MyMixins = {

    template: `<wrapper-component>
        <div>
            Whatever HTML code here
        </div>
    </wrapper-component>`,


    components: {
        WrapperComponent,
    },
};

当我们使用此mixins或子组件时,WrapperComponent中的样式将自动应用,并且可以与其他需要使用相同父样式的组件组合使用。

2
您不能将 <slot /> 用作组件根元素,因为它可能包含多个节点。除此之外,这种方法是可行的。 - Christophe Geers
这对我来说在作用域范围内无法工作(没有作用域时可以工作,但我需要作用域样式)。 - Julian

3

1
“CSS Modules”并不符合我的需求。它只是像添加另一层CSS,但可以作为一个不错的选择。 - spicydog

1

我刚把我的fadeTransition.css文件放到了我的vue应用程序的/assets文件夹中,并像这样导入:

<template>
  <transition name="fade">
    <div v-if="showContent">test</div>
  </transition>
</template>
<script>
  import '@/assets/fadeTransition.css';
  // component definition
</script>

fadeTransition.css

/* fade menus in, not out */
.fade-enter-active {
  transition: opacity .5s;
}
.fade-enter {
  opacity: 0;
}

简洁明了。也适用于scss。

干杯!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接