Vue SFC add global Sass variables to all components - vue.js

Im my webpack config I add a path
"mixins": path.resolve(
__dirname,
"resources/assets/sass/mixins/mixins.scss"
),
Which means in all my single file components I use
<style lang='scss' scoped>
#import '~variables';
This works fine but what I am finding is this file is used in 95% of components so the import really is unnecessary. I want these vars available everywhere.
How can I globally add my SASS to my single file components without the need for the import in every file?

Well, Load your common CSS from Webpack and make it available globally for all the component. Webpack configurations are as below.
sass-loader also supports a data option which allows you to share common variables among all processed files without having to explicit import them
module.exports = {
css: {
loaderOptions: {
sass: {
data: `
#import "#/scss/_variables.scss";
#import "#/scss/_mixins.scss";
`
}
}
}
};
In here, specifing the sass loader under the loaderOptions option. Just like that, all the code in those files will be available in the global scope. So from any component we can use it out of the box:
And now you can able to access the variable in your Vue SFC without importing it.
<style lang="scss">
.classroom {
/* No need to import, it just works \o/ */
background: $bg-classroom;
}
</style>
Reference Official Docs here
Hope this helps!

Related

Importing SCSS variables in Vue components

I recently switched from Vue-CLI to laravel-mix, the usage of SCSS variables worked perfectly with Vue-CLI and now doesnt seem to work anymore at all after I switched to laravel-mix.
Vue-CLI just handled everything for me and I feel like I have to configure something to get the variables to work in laravel-mix.
This is what I've tried (and what worked with Vue-CLI):
// vue component
import variables from "#/styles/variables.scss";
// ...
data() {
return {
variables
}
}
methods: {
test() {
console.log(this.variables)
}
}
// scss
$variable: #FFFFFF;
:export {
variable: $variable;
}
Edit: To clarify, this log outputs an empty object, not undefined.
For this thing to work you need to follow that particular steps
Make Your Variables File. As you made your scss file inside your style its not good you need to make inside /assets/sass/
Add Variables File To App.scss. For that thing you need to import newly create file inside your app.scss by #import 'folder/file';
Add Alias To webpack.mix.js. What we essentially need to do is define an alias or variable that contains the path to our sass directory so we can include that SASS in our Vue components. Just add alias like this in your webpack
resolve: {
alias: {
'#': path.resolve('resources/assets/sass')
}
}
Last thing add Navigation Vue Component. You can import scss variables by adding #import '~#/folder/fie.scss'; in the vue component

Can't access CSS variables in script tag of Vue file

Problem
I am trying to access variables defined within an SCSS file from a .vue file. The project is using vue-cli.
According to Vue's docs:
"Vue CLI projects comes with support for PostCSS, CSS Modules and pre-processors including Sass, Less and Stylus."
However, if I create a variables.css file with a variable called variable, and try to import it within the script, this variable is not found.
styles/variables.module.css
$variable: 'foo';
:export {
variable: $variable
}
App.vue
<script>
import variables from "./styles/variables.module.scss";
export default {
name: "App",
methods: {},
computed: {
variable() {
console.log(variables); // Object {}
return variables.variable || "not found";
}
}
};
</script>
Importing the variables.css file within the <style module> tag of the same vue file does work however.
App.vue
<style module lang="scss">
#import "./styles/variables.module.scss";
:export {
variable: $variable;
}
</style>
What I'm trying to achieve
<p>Importing within <script>, the variable is {{variable}}</p>
// 'not found', should be "foo"
<p>Importing within <style>, the variable is {{$style.variable}}</p>
// correctly showing "foo"
Have tried:
Adding .module to the SCSS file name (as per vue's docs)
Creating a vue.config.js file with requireModuleExtension: false
(from same docs)
Reproducible demo
https://codesandbox.io/s/importing-css-to-js-o9p2b?file=/src/App.vue
You need to add webpack and CSS modular code into webpack.config.js.
npm install -D vue-loader vue-template-compiler webpack
Here is the working demo
Note: your vue-template-compiler and vue should be the same version

Separate global basic styles from every page using webpack in vue-cli3

I'm using Vue-cli3.x, which is a multiple-pages project. I'm using SCSS in this project and separating the global basic styles with loaderOptions as following:
The styles relations like this: basic styles ---> components' styles ---> pages' styles
But after I building my project, I found my CSS files include basic styles more than once.
EX: dashboardAirLeft page includes chunk-common.css and dashboardAirLeft.css, however in chunk-common.css and dashboardAirLeft.css all have normalize.scss code, like following:
And my production's Webpack config like this:
My destination is to separate the common code from my page-name css file
Using loaderOptions data property means that the files you import will be imported into every single components <style> tag. So each page-name css file will also import all three of the scss files you've defined. Instead, you probably want to import the common scss files only once in the App.vue component (or main entrypoint):
App.vue
<template>...</template>
<script>...</script>
<style lang="scss">
#import "#/assets/styles/scss/normalize.scss"
#import "#/assets/styles/scss/base-style.scss"
</style>
However, you do want the variables-custom.scss file imported into each page though so that you have access to your scss variables in each component. So you should leave only variables-custom.scss in your loaderOptions:
vue.config.js
css: {
loaderOptions: {
sass: {
data: "#import '#/assets/styles/scss/variables-custom.scss'"
}
}
}

Less loader in vue-cli project

I am trying to use a less file in my vue-cli created project.
Also the question if this is best practice. Earlier I added webpack globally and started a watcher and added a webpack.config.js
This time I created the project with vue-cli / vue ui and the doc says I have to use a vue.config.js where I do this:
module.exports = {
css: {
loaderOptions: {
// pass options to sass-loader
less: {
// #/ is an alias to src/
// so this assumes you have a file named `src/variables.scss`
data: `#import "#/all.less";`
}
}
}
}
I added the file in src/all.less and also tried src/assets/less/all.less and changed the path in the config file. Both do not seem to work tho.
For me the issue was I had the language for one component set as "less" when I had in my config set up just vanilla css:
<style lang="less" scoped>
//styling here
</style>
instead of
<style lang="css" scoped>
//styling here
</style>
If you are using vue cli 3 . just use less right in your vue file, just set the lang to "less" or "scss" - pretty handy. There should be no additional configuration on the webpack side :
<style lang="less">
#import './less/index.less';

Importing external sass in Vue

I'm importing bulma into Vue (installed via vue init webpack-simple ) and I can't seem to figure out how to get it to load my own external sass files.
I have it set up like this:
<style lang="sass" src="./sass/initial-variables"></style>
<style lang="sass" src="bulma"></style>
The tag pulling bulma in works just fine, but I get an error looking for my initial variables file:
ERROR in ./src/App.vue
Module not found: Error: Can't resolve './sass/initial-variables' in
'/Users/johnbriggs/Sites/mimismarket/src'
In my src folder, I have a sass directory with initial-variables.sass as a file.
What am I missing here?
It looks like you're missing the .sass. extension in your <style> tag. Webpack might take that relative import literally.
One thing I like to do to keep my single-file components clean is to have one <style> tag and then #import my SASS files:
<style lang="sass">
#import 'bulma'
#import './sass/initial-variables' // we don't need the extension here
</style>
Another thing to keep in mind is that you can import CSS/SASS files in your JavaScript, too. It's really handy for global stylesheets:
// main.js
import 'bootstrap/dist/css/bootstrap.min.css'
You can do the following in your webpack.config:
loader: 'vue-loader',
options: {
extractCSS: true,
loaders: {
sass: ExtractTextPlugin.extract({
use: 'css-loader!postcss-loader!sass-loader?indentedSyntax&data=#import "./sass/initial-variables.sass"',
fallback: 'vue-style-loader'
})
}
}