Vue interpolation for key-value pairs - vue.js

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 }"

Related

Vue Element UI dynamically changes el-select color

I tried to modify el-select to match the color of el-option.
The methods I search on the Internet always require me to modify the style scoped . It is a static method and cannot be changed dynamically.
My expectation is when I select "WIP" in the options, it will become a yellow label in el-select according to the color in the options.
The following is a rough demo I created in Codesandbox.
https://codesandbox.io/s/dynamically-change-el-select-color-based-on-status-v0u8d?file=/src/views/Editor.vue
Your kind assistance will be greatly appreciated, thank you very much.
You could set the class of the el-select based on that you could color the input value based on the selected value
<el-select
v-model="scope.row.status"
:class="getStatusColorClass(scope.row.status)"
placeholder="Select"
>
<el-option
v-for="(status, index) in statusList"
:key="index"
:label="status.name"
:value="status.id"
>
<span :style="{ color: status.color }">{{ status.name }}</span>
</el-option>
</el-select>
JS:
methods: {
getStatusColorClass(id) {
if (!id) {
return {};
}
return this.statusList.find(status => status.id === id).name;
}
}
SCSS:
<style lang="scss">
.Approved input {
color: #00A86B;
}
.Retake input {
color: #ED2939;
}
.WIP input {
color: #FCE205;
}
</style>
After a ton of research, finally I found the solution.
The following is a rough demo I created in Codesandbox.
https://codesandbox.io/s/dynamically-change-el-select-color-based-on-status-v2-od8gn?file=/src/views/Editor.vue
I'm not sure if this is the best method, but this method has solved my problem. If you have a better solution, welcome to provide here.
Thank you very much!

Vue js bind multiple style properties to an element

This would bind background-color property to the <td> element.
<td :style="{backgroundColor: (props.item.release_date ? 'green' : 'transparent' ) }">
Some text
</td>
But what if I want to bind NOT ONLY the backgound-color same time I want to bind the foreground color (Normal color property) as well.
How do I bind multiple style properties to an element?
First of all, there's no foreground color in css. You can use multiple style with comma separated key: value pairs like:
:style="{
backgroundColor: (props.item.release_date ? 'green' : 'transparent' ),
color: 'red',
width: '120px'
}"
I was in a situation where I couldn't put all the styles in one object so I found this alternate way of style binding in vue:
vue style binding, Object syntax
vue style binding, Array syntax
basically you can have multiple style object and pass them as array to the style attribute like this:
:style="[styleObjectOne, styleObjectTwo]"

Vue inline conditional if?

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.

vuetify: calculate grid width by passed props

I want to make a menu component that builds same-sized buttons based on the amount of menuItems passed in as props.
similar to
https://stackoverflow.com/a/47215040/6066886
i want to give the v-flex a conditional attribute. (xs6 for two items, xs4 for three and so on)
(something like <v-flex v-for="item in menuItems" xs[12 / menuItems.length]>)
in the linked question, the idea is to pass "xs10" or not, based on a condition.
i want to calculate WHICH of those will be added to my v-flex, but i have no idea how that would be done.. as i can't v-bind anything... can anyone help me?
You can bind a computed property as class object:
<v-flex :class="xsComputed" v-for="(item,i) in items" :key="i">{{item}}</v-flex>
...
new Vue({
el: '#app',
data: function() {
return {
items: [1, 2, 3, 4]
}
},
computed: {
xsComputed: function() {
var step = Math.floor(10 / this.items.length)
var xsc = {}
xsc['xs' + step] = true
console.log(xsc)
return xsc
}
}
})
https://jsfiddle.net/26zfLn8j/
Ok, I see your problem now. I was digging around a little and it's not easy to solve, cause the v-flex doesn't support params, it should be declared as a attribute and not class (as says this response https://stackoverflow.com/a/47215040/6058255).
As there as no way to create a attribute without value, like I said in the comment, and affter some tests, I will do as follow:
<v-flex v-bind:class="'xs'+12/menuItems.length" v-for="menuItem in menuItems">
{{menuItem}}
</v-flex>
This should render the v-flex element with a class like: "xs12","xs6","xs4"..
The then you should only copy the class style for this elements that have the v-flex for it, something like:
.xs12{ max-width:100%; }
.xs6{ max-width: 50%; }
.xs4{ max-width: 25%; }
.xs3{ max-width: 33.333333333%; }
...
Maybe is not the more elegant solution but it's easy and it works for you I think.
Hope it helps!
EDIT:
Reviewing stdob-- answer I now see that only with the expression:
<v-flex v-bind:class="'xs'+12/menuItems.length" v-for="menuItem in menuItems">
{{menuItem}}
</v-flex>
Should work. The flex component will render as flex xs12 (for instance).

How to v-bind background?

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'}">