I have the following piece of code:
<div
:id="'object' + object.id""
:style="'position:absolute !important; width:' + object.width + '% !important; height:' + object.height + '% !important;'">
<div
This works fine and renders nicely as it should.
I now want to add conditional stuff in there. Something like
if object.background == 'solid'
background-color: #ffffff;
endif
I tried achieving this via the Vue inline if, which gave me this:
[object.background == 'solid' ? background-color: #ffffff important; :
'']
But that just gave a lot of errors, which lead me to think I'm tackling this all wrong.
What would the correct approach be for me to achieve having short conditional statements in my style?
I would use a computed property that returns a style object.
new Vue({
el: "#app",
data: {
width: '200px',
height: '200px',
background: 'solid',
},
computed: {
styleObj() {
return {
position: 'absolute !important',
width: `${this.width} !important`,
height: `${this.height} !important`,
background: this.background === 'solid' ? 'green' : 'yellow',
};
},
},
})
<script src="https://cdn.jsdelivr.net/npm/vue#2.5.17/dist/vue.min.js"></script>
<div id="app">
<div :style="styleObj">
</div>
</div>
I don't know if this should be marked as a duplicate of this question: Condition in v-bind:Style
However, this method is documented only for classes binding, on https://v2.vuejs.org/v2/guide/class-and-style.html
That said, you ask:
What would the correct approach be for me to achieve having short conditional statements in my style?
I don't think this is a correct approach. I mean, the correct approach would be to write css classes and apply them conditionally, since those are the documented methods, leave this for cases when you have to apply direct styling to override all other styles that apply to the element in question.
Other correct approach would be to use data, props, or even a computed property or method.
Also, you can have both style and :style attributes and vue will mix them for you, so you can define base style on the normal attribute and "other stuff" on the style binding.
But as i say, leave this for extreme cases where you really need this on the style attribute.
Related
I am trying to set my div width from a computed value, but I don't know how to archive it.
Case: I have some products which the informations comes from an API, and the length value changes depending on the product I selected, for this reason this component should be Dynamic.
The customer wants somethins like this:
That means, the lenght value should be also my div/span width, when the value is 10, should be 10% green, 29, 29% green etc.
Here's my code:
<li>
<span class="detail-name">foo</span>
<div class="progress" :style="getDataClass" ></div>
<span class="bold-value">{{something}}</span>
</li>
"getDataClass" is a computed value which comes from Store
First, I filter the data:
getData () {
return this.product.find(meta => meta.key === 'length_value').value
},
this function gives me the value '63'. Afther it I add this value to use with Style:
getDataClass() {
return {width: this.getData + '%'}
},
This gives me the value { "width": "63%" }
And this is my SASS (Bulma)
.progress
position: relative
flex: 1
margin: 0 8px
height: 10px
background-color: $color-grey
&::before
content: ''
position: absolute
width: 100%
height: 100%
background-color: $color-green
Can someone please help me ?
I saw it already working on my Vue course, but I am missing something or it does not aplly for this case
I hope I could explain it correctly, thank you very much for your help.
Is getData a method or a computed value?
If it is a method, the following might help:
getDataClass() {
console.log("C:",{width: this.getData() + '%'});
console.log("C:",{width: this.getData + '%'});
return {width: this.getData() + '%'}
}
Suppose that I have a data property in Vue.js called iconsColor, which is defined like this:
data() {
return {
iconsColor: "#b5ffff",
};
},
I want to be able to use this property where I am setting color like this:
:style="{ color: '#b5ffff' }"
I tried a couple of different ways
:style="{ color: '{{iconsColor}}' }"
and studied a few interpolation techniques like this and this, but I was not able to come to a solution. How this utilization can happen?
Based on this section the style could be bound to the data property as follows :
:style="{ color: iconsColor }"
I am trying to give an element in my page a custom colour but all attempts are foiled by the Vuetify enforcing the important! on the component themes. I have followed the docs and tried:
v-list-item.selection(class="red--text")
and
v-list-item.selection(color="red")
then got desperate and tried
.selection {
color: red
}
and
.theme--light.v-list-item {
color: red
}
But the theme color just overrules everything by applying:
.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {
color: rgba(0, 0, 0, 0.87) !important;
}
What do?
You can overwrite it by adding the same rule in your App.vue:
.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled) {
color: red !important;
}
Or you can increase specificity by adding your own class to that element:
<div class="custom-list-item"></div>
...
.custom-list-item {
color: red !important;
}
Or you can specifically change color of all elements inside it, if it works for you:
.theme--light.v-list-item * {
color: red !important;
}
One might work (but not a good practice at all):
.theme--light.v-list-item:not(.v-list-item--active):not(.v-list-item--disabled).selection {
color: red !important;
}
// it's more than Vuetify's style the `.selection` specificity
Edit:
The answer I gave above will not work if you use scoped style
As working around myself, and have read a comment here. I don't think change Vuetify's style in a Vuetify component is easy. Instead, by using a Vuetify's component, you should predefine the colors you'll ever use, and then you could use those colors in the components you want.
To workaround without configuring Vuetify, then you can:
Combine inline style + !important
<v-list-item style="color: red !important">Content</v-list-item>
Don't use Vuetify's component, use vanilla html (for this component) instead
I just started learning Vue and I was wondering, why should I use v-bind for style and not write it regularly in html/css file
Let's say you need to create a progress bar that is not static. You will then need to update the style attribute width for-example.
To accomplish this, we need to programatically edit the width of the element. We 'cannot' to this in plain css, therefore the :style attribute comes in handy.
Let's create an example:
Codepen
HTML
<div id="vue">
<div class="progress-bar">
<div :style="{'width':progress + '%'}" class="progress" />
</div>
<button #click="fakeProgress">Init fake progress</button>
</div>
Css;
.progress-bar, .progress {
border-radius: 20px;
height: 20px;
}
.progress-bar {
width: 250px;
background-color: gray;
}
.progress {
background-color: blue;
width: 0;
transition: all 1s ease;
}
Javascript
new Vue({
el: '#vue',
data: {
progress: 0
},
methods: {
fakeProgress() {
let progress = setInterval(() => {
if(this.progress == 100) {
clearInterval(progress)
} else {
this.progress += 1;
}
}, 50)
}
}
})
As you see here, we bind the progress data attribute to the width value on the fake progress bar. This is just a simple example, but I hope this makes you see its potential. (You could achieve this same effect using the <progress> tag, but that would ruin the explanation.
EDIT; Also want to point out that you are supposed to write all your css as normal as you point out in your question. However, :style is used in cases that you cannot normally use css for. Like the example above where we need css to change from a variable.
Im trying to do something like this:
<div class="seller_image" :style="{background: url(' + user_credentials.avatar +'); background-size: cover !important; display:block;}">
but i get this error:
Invalid expression. Generated function body: {background:scope.url('
+ user_credentials.avatar +');scope.background-scope.size:scope.cover!scope.important;scope.display:scope.block;}
Any suggestion?
Like this it working but i want to use it like background image:
<img v-bind:src="user_credentials.avatar" alt="Avatar" />
It's easier to put this together inside a computed and use that instead:
new Vue({
el: '#app',
computed: {
getBackground() {
return 'background: url(' + this.user_credentials.avatar + '); background-size: cover display:block;';
}
},
data: {
user_credentials: {
avatar: 'avatar.png'
}
}
})
Then you can use it like so:
<div :style="getBackground"></div>
Here's the JSFiddle:
https://jsfiddle.net/w6agzuen/
The error you are getting is because you need the background value to be a string. Any additional inline styles need to be comma delimited then as well because you are passing an object. Lastly I believe styles like background-size that contain a hyphen need to be camel-cased when binding them so then the final changes to your inline styles should look like this:
<div class="seller_image" :style="{background: 'url(' + user_credentials.avatar +')', backgroundSize: 'cover !important', display: 'block'}">