16

Is it possible to use a variable with the style tag of a component? Basically I have imported a mixin to my style tag that accepts 2 colors to create a gradient within a class. It works great but I want this dynamic so I can set it via a database. I understand I can bind a style via inline but a gradient for a div is rather long and works way better as a mixin.

component:

<template>

    <section class="section" v-bind:class=" { 'color-section' : content.gradient_color_one }">

        <div class="container">

            <div class="columns">

                <div class="column is-half">

                    <h2 class="is-size-4" v-html="content.title"></h2>

                    <div class="section-content" v-html="content.description"></div>

                    <a class="button" :href=" '/'+ content.button_link">{{ content.button_text }}</a>

                </div>

                <div class="column">

                    <img :src="content.image" :alt="content.title" />

                </div>

            </div>

        </div>

    </section>

</template>

<script>
    export default {

        props:[
            'content'
        ],

    }
</script>

<style lang="scss" scoped>

    @import "../../sass/helpers/mixins";

    .color-section{
        color:red;
        @include diagonalGradient( content.gradient_color_one , content.gradient_color_two);
    }

</style>

mixins

@mixin diagonalGradient($top, $bottom){
  background: $top;
  background: -moz-linear-gradient(-45deg, $top 0%, $bottom 100%);
  background: -webkit-gradient(left top, right bottom, color-stop(0%, $top), color-stop(100%, $bottom));
  background: -webkit-linear-gradient(-45deg, $top 0%, $bottom 100%);
  background: -o-linear-gradient(-45deg, $top 0%, $bottom 100%);
  background: -ms-linear-gradient(-45deg, $top 0%, $bottom 100%);
  background: linear-gradient(135deg, $top 0%, $bottom 100%);
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#92fe9d', endColorstr='#00c8ff', GradientType=1 );
}
Packy
  • 3,405
  • 9
  • 50
  • 87
  • I don't think there is a way to easily do this. If the linear-gradient was a composit property it might have been easier. This might make it a bit easier less of a hassle for you: https://vuejs.org/v2/guide/class-and-style.html#Multiple-Values – Stephan-v Sep 01 '17 at 07:22

3 Answers3

11

In Vue 3 you can now use v-bind in single file component <style> sections like this:

<style scoped>
.color-section {
  color: v-bind('sectionColor');
}
</style>
Maccesch
  • 1,998
  • 1
  • 18
  • 27
6

You should use computed properties, as they probably are the best and cleanest way to achieve what you're trying to do. They also have a whole site about it on the Vue Docs:

https://v2.vuejs.org/v2/guide/class-and-style.html

Basically, you COULD do something like this:

computed: {
  style () {
    return 'background: ' + this.top + ';' + '...'
  }
}

Instead of passing the mixin, you could then pass the top and bottom variables. This is quite handy because in your computed style () function you have the freedom to do any javascript related stuff you want, so you can have conditionals, expressions and whatnot. Gives you powerful control over your style ;)

tony19
  • 125,647
  • 18
  • 229
  • 307
fweidemann14
  • 1,714
  • 3
  • 13
  • 20
  • 3
    This method worked and looks the cleanest code wise. It would be nice in the future if Vue team could get a variable to work in the – Packy Sep 01 '17 at 19:08
  • 1
    I agree.. there are tons of things I wish they would implement in the future, it could make development with Vue much nicer.. – fweidemann14 Sep 03 '17 at 06:34
  • 1
    How about if these styles are to be added to pseudo elements like ::after? – Eric McWinNEr Mar 28 '20 at 23:24
1

as we can see from @Maccesch's answer you can now use v-bind() in <style></style> section of vue sfc (.vue file) as of vue3, I found his answer very useful so I tought it's worth mentioning some notes:

as vue3 docs states :

The syntax works with <script setup>, and supports JavaScript expressions (must be wrapped in quotes):

so we only need to use quotes when we are going to use a js expression in our style block.

another thing to note, I didn't see anything mentioned about using const color3 = ref('green') in vue docs and when I tried it in a vue playground I found out it will get unwrapped automatically and we don't need to use v-bind('color3.value') and we can use it like v-bind(color3).

take a look at examples:

<template>   

<h1>Header number one</h1>
<h2>Header number two</h2>
<h3>Header number three</h3>

</template>

<script setup> 

const theme = {color:'red'} 
const color2 ='blue'
const color3 = ref('green')

</script>

<style scoped>

    /* we don't need to use quotes here */
 h1 {
    color: v-bind(color2); 
} 

    /* we are using quotes here (' ') because theme.color is a javaScript expression */
 h2 {
    color: v-bind('theme.color'); 
} 

 h3 {
    color: v-bind(color3); 
} 
</style>
w3bsite
  • 181
  • 1
  • 10