Какой лучший способ использовать v-bind для псевдоклассов, таких как :hover и :active, и возможно ли это сделать в принципе?

Как можно добавить стили для псевдоклассов, таких как <code>:hover</code>, <code>-autofill</code>, <code>:not(:last-of-type)</code> и т.д., в том случае, если я использую синтаксис <code>:style</code> для HTML-тега?
  • 6 сентября 2024 г. 14:52
Ответы на вопрос 2
В Vue.js, когда вы используете `v-bind` для динамического связывания стилей, например, с помощью `:style`, вы ограничены возможностью применения стилей только в контексте текущего элемента, и не можете напрямую управлять псевдоклассами, такими как `:hover` или `:active`, через `:style`. Псевдоклассы применяются на уровне CSS и должны быть определены в стилях отдельно.

Однако есть несколько подходов для работы с псевдоклассами, когда вы используете Vue.js:

### 1. CSS классы

Используйте динамическое связывание классов с помощью `:class`. Это позволяет вам управлять стилями через классы, которые могут включать псевдоклассы:

```html
<template>
  <button :class="{ 'my-button': true, 'hovered': isHovered }" @mouseover="isHovered = true" @mouseleave="isHovered = false">
    Hover me
  </button>
</template>

<script>
export default {
  data() {
    return {
      isHovered: false,
    };
  },
};
</script>

<style>
.my-button {
  background-color: blue;
}

.my-button.hovered {
  background-color: green;
}

.my-button:hover {
  background-color: yellow; /* Псевдокласс :hover */
}
</style>
```

### 2. Использование CSS Styled Components или CSS Modules

Если вы используете библиотеки, такие как styled-components или CSS Modules, вы можете легко работать с псевдоклассами прямо в вашем компоненте:

```html
<template>
  <button class="my-button">
    Hover me
  </button>
</template>

<style scoped>
.my-button {
  background-color: blue;
}

.my-button:hover {
  background-color: yellow; /* Псевдокласс :hover */
}
</style>
```

### 3. Использование Vue's `v-bind:style` с псевдоклассами

К сожалению, нельзя использовать `v-bind:style` для применения стилей к псевдоклассам, так как `:style` привязывается к атрибуту `style`, который не поддерживает псевдоклассы. Однако вы можете создать условные стили в JavaScript и применить их к элементу, но только в контексте обычного состояния, а не псевдокласса:

```html
<template>
  <div :style="buttonStyle" @mouseover="isHovered = true" @mouseleave="isHovered = false">
    Hover me
  </div>
</template>

<script>
export default {
  data() {
    return {
      isHovered: false,
    };
  },
  computed: {
    buttonStyle() {
      return {
        backgroundColor: this.isHovered ? 'yellow' : 'blue',
      };
    },
  },
};
</script>
```

### Заключение

Для работы с псевдоклассами в Vue.js лучше использовать классы и выражения CSS, чем пытаться управлять ими через `v-bind:style`. Также рассмотрите возможность использования CSS-in-JS подходов или модулей, если ваше приложение требует динамического и интуитивного подхода к стилям.
Вопрос по большому счёту не относится к vue. 

Решения:
1. Использовать класс-модификатор, который порасит как надо.
<template>
  <input class="hover--red"/>
</template>

<style>
.hover--red:hover {
  color: #f00
}
</style>

2. Использовать css (не путать с scss) переменные.
<script setup>
// ...
const hoverColor = '#f00'
</script>

<template>
  <input :style="{'--hover-color': hoverColor}"/>
</template>

<style>
input:hover {
  color: var(--hover-color)
}
</style>


...upd: совсем забыл про такую фичу vue:
3. Если стили лежат в sfc можно использовать переменные через v-bind в <style> :
<script setup>
// ...
const hoverColor = '#f00'
</script>

<template>
  <input />
</template>

<style>
input:hover {
  color: v-bind(hoverColor)
}
</style>

А забыл я про неё потому, что категорически против такого смешения кода и стилей. Но я не могу вам запретить.:)
Похожие вопросы