Set dynamic class depending of parameter received - vue.js

I'm new using Vuejs and I have a component that I want to set height value only if I send a parameter in props
So, my class is something like this:
<input
tag="section"
class="h-full"
>
As you can see I use h-full class (tailwind framework) but I want to remove it if prop comes true, so I create a new prop:
props: {
adjustHeightToContent: {
type: Boolean,
default: false,
}
},
I want to know how can I set that CSS class to dynamic depending of parameter value
Component usage:
<BaseInput v-if="isModalShown"> </BaseInput>

Use can use this:
:class="adjustHeightToContent ? 'h-auto' : 'h-full'"

Related

bootstrap-vue table, Formatter callback error: You may have an infinite update loop in a component render function

I'm using bootstrap-vue table, according to documentation regarding formatter callback: https://bootstrap-vue.org/docs/components/table .
A variable is defined in data(), I will need this variable as a flag to control the cell content.
data() {
return {
aFlag: 0,
}
}
Then in the fields I use the formatter call back:
{ key: 'value', label: 'Value', formatter: this.updateValue},
In the methods area I use updateValue to update the flag:
methods: {
updateValue(value) {
..
aFlag = value
..
}
}
Then error "You may have an infinite update loop in a component render function." happened here.
If I want to do such a thing, is there any best practice? The cell content may cause other cell's change, so currently I use a variable to control the behavior as a flag. Thanks in adavance.
The formatter callback is only intended to change how the value is displayed to the user, not change its value.
If you want to be able to change the value, I'd suggest using a slot for the value property and use v-model on a form component within the slot:
<template v-slot:cell(value)="data">
<input type="text" v-model="data.value"/>
</template>

Ignore undefined props

I am passing an object like this into a component:
obj = {
prop1: 1,
prop2: 2,
prop3: 3
}
<my-component :data="obj"></my-component>
the component only has these two defined, by design, because I want to ignore what is not defined:
props: {
prop1: Number,
prop2: Number
}
what's happening is when the component is rendered, the root node looks like this with the undefined prop placed like an attribute?!:
<div prop3="3">
...
</div>
I don't want undefined props to be de-structured by the component and definitely don't want them to rendered in the root element. I want them to be ignored. Is there a flag or some setting to say ignore all undefined props?
Please don't say why I would ever need this. I do because these objects are built somewhere else and don't want to create new subset objects just for this purpose.
You can use:
props: {
prop1: Number,
prop2: Number
},
inheritAttrs: false
This will tell Vue to not add additional props to the element as attribute but those props will instead be stored in $attrs, so you could access your prop using this.$attrs.prop3
See https://vuejs.org/guide/components/attrs.html#disabling-attribute-inheritance

When to use ":" on property passed to component in Vue?

I've seen an example block of code in an component that passes two props down. One uses a ":" while the other doesn't. But I can't figure out why one needs and one doesn't. What does it stand for and how does it affect the info passed down?
<date-picker
format="D MMM YYYY"
:options="{ firstDay: 1 }">
</date-picker>
and inside the component
props: {
format: { default: 'YYYY-MM-DD' },
options: { default: {} }
}
: in the template is shorthand for v-bind mean for data binding which mean in your case :option is to tell that the string on the right side is javascript variable. while the latter is just a normal javascript object there no need to binding.
here some link of reference: https://v1.vuejs.org/guide/syntax.html

Passing data to Vue.js component

I am creating a component and want to pass two properties (item & brokerageID) to the component. Here is the HTML code:
{{brokerageID}}
<holiday-component v-bind:item="item" v-bind:brokerageID="brokerageID" testID="45" ></holiday-component>
Here is the code for 'holiday-component'
Vue.component('holiday-component', {
props: ['item',
'brokerageID',
'testID',
],
data () {
return {
holidaysData: [],
showHolidays: false,
}
},
methods: {
getHolidays(contactID) {
....
},
template: <div> {{testID}} {{item.contactName}} {{brokerageID}}
....
The 'item' property is getting passed to the component (item.contactName is displayed correctly in the component template. However, somehow, brokerageID (property of the Vue object) is not getting passed. This property exists which is confirmed as {{brokerageID}} used above the component in HTML displays value. But, within the component template, brokerageID is not available. Also, the testID property passed to the component is not displayed.
Could someone please advise, what is wrong in my implementation that I am unable to use brokerageID in my component?
See Vue's docs about prop naming https://v2.vuejs.org/v2/guide/components.html#camelCase-vs-kebab-case
In this instance, using v-bind:brokerage-id and v-bind:test-id should do the trick.

vue: transforms a prop in its definition

I've a component which is a button with some stuff like a icon. I use it like this:
<ti-btn icon="..." #click.native="..."></ti-btn>
also, I can pass a prop which isn't required, this prop is the size, which is a Number.
<ti-btn icon="..." size="32" #click.native="..."></ti-btn>
Now, in my component's definition, at first, I wrote:
<template>
<i :class="icon" :style="{fontSize}"></i>
</template>
<script>
export default {
props: ['icon', 'size'],
computed: {
fontSize() {
return this.size ? `${this.size}px` : DEFAULT_SIZE;
}
}
}
</script>
If the size is not passed down, I set the default value. That's works, but according to good practices and vue style guide, Prop definitions should be as detailed as possible. So, I started to use this way:
props: {
icon: {
type: String,
required: true,
validate(value){
//some kind of validation here
return value.includes('ti')
}
},
size: {
type: Number,
required: false,
default: DEFAULT_SIZE
}
}
size prop receive a Number, but, it must return a string, in fact DEFAULT_SIZE is set to "24px" which is a String, also, the value receive is transformed to value+"px". So, My question is, how can I transform the size prop in its own definition object, without use the computed property?
As Terry mentioned in the comments, it's not possible to provide a way to transform the value of a prop being passed to a component from within the prop's definition itself.
You could let size just be a Number, and then add the 'px' when you bind it to the style:
<i :class="icon" :style="{ fontSize: `${size}px` }"></i>
This would mean you'd need to make DEFAULT_SIZE equal to 24.
If you're unable to change the value of DEFAULT_SIZE. Then your example of the fontSize computed property is the correct way to handle the issue.