Using SASS in Vue Components with Laravel Mix
Part 11 of 48 in API Driven Development With Laravel and VueJSOn of the most powerful features of Vue Components or Web components for that matter is all of your CSS, HTML, and Javascript are in the same file. This makes managing all factors of the component extremely easy. If you are using SASS in your project and you want to carry in your variables for your Vue components, it can be a little tricky. It’s definitely useful though and can really help with managing your project.
Now in the tutorial about configuring Javascript and SASS for your single page application: https://serversideup.net/configuring-js-sass-single-page-app/, we built a directory structure for all of the assets of SASS. These are still useful! You can easily place your SASS for your Vue components in these directories if needed. We will still be using these directories as buckets to house our SASS as our app expands.
Step 1: Make Your Variables File
Right now, since we are using Foundation for some quick grid functionality, our most important file will be our _variables.scss file that we will include all of our SASS Variables for the app. Following the 7-1 pattern ( Sass Guidelines) we should add a file in the /assets/sass/abstracts
directory named _variables.scss
.
I added a few default colors (kind of coffee based since we are doing a coffee app) to the variables file. It should look like this:
$white: #FFFFFF;
$black: #111111;
$primary-color: #7F6D50;
$secondary-color: #FFBE54;
$highlight-color: #FFDBA0;
$dark-color: #7F5F2A;
$dull-color: #CCAF80;
We now have some colors to use in the components! If you want a cool tool for non-designers like myself, check out Adobe Color CC. Here’s the link I used to generate my coffee colors: Adobe Color CC
Step 2: Add Variables File To App.scss
We need to import our newly created variable file into our assets/sass/app.scss
file so it will be compiled into our CSS when we build our application. To do that add this line to your app.scss
file:
@import 'abstracts/variables';
Your file should look like this:
@charset "UTF-8";
/* ==========================================================================
Builds our style structure
https://sass-guidelin.es/#the-7-1-pattern
========================================================================== */
/**
* Table of Contents:
*
* 1. Abstracts
*/
@import 'abstracts/variables';
@import "node_modules/foundation-sites/assets/foundation.scss";
Step 3: Add Alias To webpack.mix.js
Now this is what ties everything together to allow use to use Laravel Mix and SASS with our Vue components. 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. 99% of the time we should just be including our variables file because we are defining all of the other styles in the Vue Component it self. I still keep all the directories for the 7-1 pattern for global styles, simple element styles like button components, custom grids if needed, etc. To add the alias add the following to your webpackConfig object in your webpack.mix.js
:
resolve: {
alias: {
'@': path.resolve('resources/assets/sass')
}
}
This solution was found here: tutorial How to use global Sass vars within Vue Single File Components · Issue #1023 · JeffreyWay/laravel-mix · GitHub. What we did is when we build our app, we resolve the @
as an alias for our resources, assets, sass directory. Our entire webpack.mix.js
file should look like:
let mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
mix.js('resources/assets/js/app.js', 'public/js')
.webpackConfig({
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules(?!\/foundation-sites)|bower_components/,
use: [
{
loader: 'babel-loader',
options: Config.babel()
}
]
}
]
},
resolve: {
alias: {
'@': path.resolve('resources/assets/sass')
}
}
})
.sass('resources/assets/sass/app.scss', 'public/css');
We added the other code to allow for a production build of foundation.
Step 4: Add Navigation Vue Component
Time to add our first Vue component to Roast and Brew! Now that we have SASS ready to compile into our Vue component, we should be ready to rock and roll with building what we need. First, add the file: resources/assets/js/components/global/Navigation.vue
. We created a global directory as well. I like to structure the components in folders for grouping especially with parent/child combinations. Just makes things easier to find. In the Navigation.vue component, stub out the following code:
<style>
</style>
<template>
<nav class="top-navigation">
</nav>
</template>
<script>
export default {
}
</script>
This is just the base for the component. Next we have to tell Vue that we are using SCSS in our <style>
tag instead of CSS. To do that add a property of lang=“scss"
to the the <style>
tag.
Next, we need to import our SCSS variables. Since we defined it to resolve @
as the root directory for the SCSS, we can add this as the first line in the style tag:
@import '~@/abstracts/_variables.scss';
Now we are importing our SCSS variables in our Navigation.vue component! It should look like this all stubbed out:
<style lang="scss">
@import '~@/abstracts/_variables.scss';
</style>
<template>
<nav class="top-navigation">
</nav>
</template>
<script>
export default {
}
</script>
This component will be our navigation bar for our application. Notice we also used a <nav
tag. I try to follow the HTML5 semantics whenever possible. If you haven’t done HTML5 semantics, I’d recommend checking out: HTML5 Semantic Elements and doing some Googling.
We now have a component that complies with SASS using Laravel Mix.
A Little More about Navigation.vue
So I added some styles to our Navigation.vue component. I’m going to preface these styles with this: this tutorial is focused on building a single page application with VueJS, Laravel and eventually transferring to mobile. I am NOT a CSS guru! Right now the styles will do and it shows how to use SASS variables with Vue components that compile with Laravel Mix.
<style lang="scss">
@import '~@/abstracts/_variables.scss';
nav.top-navigation{
background-color: $white;
height: 50px;
border-bottom: 2px solid $dark-color;
span.logo{
border-right: 1px solid $dark-color;
display: block;
float: left;
height: 50px;
line-height: 50px;
padding: 0px 20px 0px 20px;
font-family: 'Josefin Sans', sans-serif;
font-weight: bold;
color: $dark-color;
&:hover{
color: white;
background-color: $dark-color;
}
}
ul.links{
display: block;
float: left;
li{
display: inline-block;
list-style-type: none;
line-height: 50px;
a{
font-family: 'Lato', sans-serif;
font-weight: bold;
color: $black;
&:hover{
color: $dark-color;
}
}
}
}
div.right{
float: right;
img.avatar{
width: 40px;
height: 40px;
border-radius: 40px;
margin-top: 5px;
margin-right: 10px;
}
}
}
</style>
<template>
<nav class="top-navigation">
<router-link :to="{ name: 'home'}">
<span class="logo">Roast And Brew</span>
</router-link>
<ul class="links">
<li>
<router-link :to="{ name: 'cafes' }">
Cafes
</router-link>
</li>
</ul>
<div class="right">
<img class="avatar" :src="user.avatar" v-show="userLoadStatus == 2"/>
</div>
</nav>
</template>
<script>
export default {
/*
Defines the computed properties on the component.
*/
computed: {
/*
Retrieves the User Load Status from Vuex
*/
userLoadStatus(){
return this.$store.getters.getUserLoadStatus;
},
/*
Retrieves the User from Vuex
*/
user(){
return this.$store.getters.getUser;
}
}
}
</script>
You will see a couple other things in the file such as <router-link>
and some Vuex computed properties. We will touch on those in the next tutorial. I’m just showing some of the CSS I added.
We also added a few fonts that we will be using from Google Fonts in our resources/views/app.blade.php
file:
<link href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Josefin+Sans" rel="stylesheet">
We can use these fonts in our styles as well.
Conclusion
We now have a Vue component added to our our application that compiles SASS into the component using Laravel Mix. The next few tutorials will be cleaning up our app as we begin to add some unique functionality to the app.