Reputation: 39
I'm using Bootstrap-Vue in a VueJS project, and it's being impossible using a class..
I have the next input
<div class="input__wrapper">
<b-form-input
v-model="idOrNameSelected"
class="textfield"
:class="{'input--empty': idOrNameSelected != null}"
@keydown.enter.native="onSubmit" />
<label
class="input__label">Service id or name</label>
</div>
In my script section I defined idOrNameSelected like:
data () {
return {
idOrNameSelected: ''
}
}
In my scss file I have a rule like
&:focus ~ .input__label,
&:not([value=""]) ~ .input__label {
top: 8px;
pointer-events: none;
}
And when I put any text in my input never is using this css rule, why?????
Thanks
Upvotes: 0
Views: 1727
Reputation: 768
Here's the problem. The CSS logic doesn't know about Vue observers or v-model
so it doesn't update the way you think. Take a step back and try this simple example:
HTML
<input class="in" type="text" value="bar" />
<label class="lab">Test</label>
CSS
.in:not([value="foo"]) ~ .lab {
color: crimson;
}
As you can see, the label is now red. Now try changing the value="foo"
you'll see the label
switches colors. But, what you should note here is that it doesn't have any sort of 2-way binding on the CSS itself, but actually just takes the current value in the actual DOM.
To provide you with an actual solution, I would use a class binding in this case. You can read about them here: https://v2.vuejs.org/v2/guide/class-and-style.html
Essentially, it allows you to dynamically add/remove a class based on some true condition. And you can actually use your v-model in there.
Here's an example of how I would do it:
<template>
<div id="app">
<input type="text" v-model="model">
<label :class="{error: model === ''}">Label</label>
</div>
</template>
<script>
export default {
name: "App",
data() {
return { model: "" };
}
};
</script>
<style scoped>
.error {
color: crimson;
}
</style>
Upvotes: 2
Reputation: 5435
@dev-cyprium is correct regarding Vue not placing the attribute value
on the input element when using v-model (value
is actually a domProp on the element)
There is a trick you can do with data attributes though:
<template>
<div>
<b-form-input id="the-input" v-model="value" :data-value="value"></b-form-input>
<label for="the-input">Hello World</label>
</div>
</template>
<style>
input.form-control ~ label {
color: red;
}
input.form-control[data-value=""] ~ label {
color: blue;
}
</style>
<script>
export default {
data() {
return {
value: ''
}
}
}
</script>
Upvotes: 1