tl;dr:如何将一些具有全局样式的.scss
文件自动导入到其他文件以及Vue的单文件组件
我有一个Vue项目被配置为自动导入一些全局样式:
// vue.config.js
module.exports = {
// Automatically import global styles:
css: {
loaderOptions: {
scss: {
prependData: `
@use "@/global/styles/_Colors.scss";
@use "@/global/styles/_Mixins.scss";
`
}
}
}
}
这非常适合于使用@use自动导入全局样式到每个File组件中:
<!-- Component.vue -->
<template>...</template>
<style lang="scss">
.hero {
background: Colors.$primary; // _Colors.scss was automatically imported with @use!
}
</style>
但是,如果我在一个单独的文件中定义组件样式,然后将该文件导入组件中,如下所示:
// ComponentStyles.scss
.hero {
background: Colors.$primary; // Error! "There's no module with the namespace "Colors"
}
<!-- Component.vue -->
<template>...</template>
<style lang="scss">
@use "./ComponentStyles";
</style>
我尝试使用style-resources-loader
插件,下面是自动进口 Vue文档中的示例配置,如下所示:
// vue.config.js
const path = require('path')
module.exports = {
chainWebpack: config => {
const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
types.forEach(type => addStyleResource(config.module.rule('scss').oneOf(type)))
},
}
function addStyleResource (rule) {
rule.use('style-resource')
.loader('style-resources-loader')
.options({
patterns: [
path.resolve(__dirname, './src/global/styles/_Colors.scss'),
path.resolve(__dirname, './src/global/styles/_Mixins.scss')
],
})
}
而且起作用了。有点。我现在已经可以访问我的全局样式,甚至在.scss
文件中也是如此(不仅仅是在SFCs中)。但是,一个新的错误出现了。在Vue组件中导入具有@use
的本地组件样式不再有效。
<!-- Component.vue -->
<template>...</template>
<style lang="scss">
@use "./ComponentStyles";
// Error! @use rules must be written before any other rules.
</style>
我猜,在第二种方法中,style-resources-loader
插件使用的是@import
规则,或者在SFCs中将全局样式的内容倾倒在本地@use
规则之上。这将导致我看到的错误,但我找不到任何选项来控制它。
目标:
我希望能够使用@use
规则自动添加导入到SFCs中的@use
文件,这些规则将全局样式公开给这些文件(就像我使用SFCs的第一种方法中的vue.config.js
中的loaderOptions
属性一样)。我想保持我的SFCs尽可能干净,这就是为什么我更喜欢把我的组件样式分解成单独的文件。
那么,是否有任何方法可以自动将一些.scss
.scss
文件导入到Vue的单个文件组件以及其他具有 @use
规则的文件中?
提前感谢您的帮助。
发布于 2022-07-29 02:43:07
更新:大部分已解决
我设法:
.scss
或.sass
文件轻松访问全局Sass样式。唯一的小麻烦是,我必须手动将全局样式导入Sass文件(它们只会自动导入Vue组件)。但是,我使用的设置支持别名,所以如果我移动样式文件,我不需要担心构建相对路径或更新导入语句。另外,与我以前的设置不同,新的设置完全支持最新的@use
语法。
安装指南
注意:我现在使用的是Vite而不是Vue Cli。
注2:我做了一个最低限度的回购,以防您更喜欢探索如何设置这一点的更详细的演示.
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
// Config Docs: https://vitejs.dev/config/#css-preprocessoroptions
css: {
// make global variables and mixins available in all Vue components:
preprocessorOptions: {
sass: {
additionalData: `
@use './src/global/Index' as GlobalStyles
`
// ...I chose to merge all my GlobalStyles into one single scope here,
// but you can also import them individually.
}
//...you can change the key above from 'sass' to 'scss' if you use scss in
// your Vue components. You could also repeat the same settings for both if
// you alternate between sass and scss in your components. Note that this
// distinction is not needed for the ".sass" or ".scss"" files you import into your
// Vue components. Those are handled by the alias resolver below, which will work
// regardless of the Sass file extension you use.
}
},
resolve: {
alias: [
{
// This will help us use our global styles from regular sass files:
find: '@styles',
replacement: path.resolve(__dirname, 'src/global/Index')
}
]
}
})
全局变量示例
// Colors.sass
$aquamarine: hsl(160, 100%, 75%)
$deepSlateGray: hsl(160, 25%, 5%)
$faintAqua: hsla(160, 100%, 95%, 0.25)
全局混合实例
// Mixins.sass
@mixin useCenteredFlex($direction)
display: flex
flex-direction: $direction
justify-content: center
align-items: center
全局样式聚合器
注意:这与Colors.sass
和Mixins.sass
位于同一个目录中,也是我要自动导入所有Vue组件并将@style
别名与之匹配的文件。
// Index.sass
@forward 'Colors'
@forward 'Mixins'
从Vue组件访问全局样式的演示
<template>...</template>
<style lang="sass">
body
@include GlobalStyles.useCenteredFlex(column) // <- using a globally available mixin
background-color: GlobalStyles.$deepSlateGray // <- using a globally available variable
</style>
从Sass文件访问全局样式的演示
// Here we need to reference the alias we set up in vite.config.js to access our GlobalStyles
@use '@styles' as GlobalStyles
h1
color: GlobalStyles.$aquamarine // <- using a global variable
[1]: https://github.com/mareszhar/demo-asiivwv-so
https://stackoverflow.com/questions/69804743
复制相似问题