【问题标题】:VueJS - v-bind:style + hoverVueJS - v-bind:style + hover
【发布时间】:2017-10-03 19:23:58
【问题描述】:

我需要将 CSS 悬停与 VueJS v-bind:style 指令一起使用,但找不到有关它的信息。

我需要为悬停绑定样式但是v-bind:style.hover={} 不起作用。所有的属性都将从后端获取,所以我需要动态绑定样式。

是否有其他方法可以使用 VueJS 在鼠标悬停或 CSS 悬停时绑定样式?

这是我的代码

这是对象:

button: {
    colorBackd: '#1e2021',
    colorBackdHover: '#000000',
    text: 'Results',
    color: '#d3e0ff',
    colorHover: "#ffffff",
    borderColor: '#d3e0ff',
    borderColorHover: "#ffffff"
},

这里是需要绑定样式的html元素

<button type="button"
    :style="{
    color:button.color,
        backgroundColor:button.colorBackd,
        borderColor:button.borderColor,
    }"
    class="btn btn-outline-info large-button">

        {{ button.text }}

</button>

谢谢

【问题讨论】:

标签: vue.js vuejs2


【解决方案1】:

改进的解决方案:使用 CSS 自定义属性和变量

如果您只打算使用现代/常青浏览器,那么使用 CSS 自定义属性和变量是不错的选择!您实际上可以将 CSS 自定义属性传递给 :style 绑定,例如

computed: {
  styleObject: function() {
    return {
      '--color': this.button.color,
      '--color-hover': this.button.colorHover
    }
  }
}

在你的模板中:

<custom-button :style="styleObject" />

对于 CSS,这只是一个问题:

button {
  color: var(--color);
}

button:hover {
  color: var(--color-hover);
}

这种方法的优点是您可以限定 CSS 自定义属性,因此当您在元素级别(而不是在 :root 中)定义 CSS 属性时,这些变量只会应用于您的特定按钮组件。

唯一的缺点是您必须在悬停和未悬停状态下迭代声明所有变量,这可能有点麻烦。但是,与使用 CSS 变量所带来的好处相比,我认为这是一个非常小的缺点。

请参阅下面的概念验证:

var customButton = Vue.component('custom-button', {
  template: '#custom-button',
  data() {
    return {
      button: {
        colorBackd: '#1e2021',
        colorBackdHover: '#000000',
        text: 'Results',
        color: '#d3e0ff',
        colorHover: "#ffffff",
        borderColor: '#d3e0ff',
        borderColorHover: "#ffffff"
      }
    };
  },
  computed: {
    styleObject() {
      return {
        '--button-color': this.button.color,
        '--button-background-color': this.button.colorBackd,
        '--button-border-color': this.button.borderColor,
        
        '--button-color--hover': this.button.colorHover,
        '--button-background-color--hover': this.button.colorBackdHover,
        '--button-border-color': this.button.borderColorHover
      };
    },
  },
});

new Vue({
  el: '#app'
});
button {
  color: var(--button-color);
  background-color: var(--button-background-color);
  border-color: var(--button-border-color);
}

button:hover {
  color: var(--button-color--hover);
  background-color: var(--button-background-color--hover);
  border-color: var(--button-border-color--hover);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
  <custom-button></custom-button>
</div>

<script type="text/template" id="custom-button">
  <button type="button" :style="styleObject" class="btn btn-outline-info large-button">
        {{ button.text }}
  </button>
</script>

原方案:使用基于JS的鼠标事件

您可以将元素的悬停状态存储在其data 中,例如hoverState。默认设置为false,触发@mouseenter时切换为true,触发@mouseleave时切换回false

然后,您可以简单地将计算属性绑定到style 属性,例如styleObject。在这个styleObject 中,您可以根据组件数据中的hoverState 返回正确的CSS 样式:

var customButton = Vue.component('custom-button', {
  template: '#custom-button',
  data() {
    return {
      button: {
        colorBackd: '#1e2021',
        colorBackdHover: '#000000',
        text: 'Results',
        color: '#d3e0ff',
        colorHover: "#ffffff",
        borderColor: '#d3e0ff',
        borderColorHover: "#ffffff"
      },
      hoverState: false
    };
  },
  computed: {
    styleObject() {
      var modifier = '';
      if (this.hoverState)
        modifier = 'Hover';
        
      return {
        color: this.button['color' + modifier],
        backgroundColor: this.button['colorBackd' + modifier],
        borderColor: this.button['borderColor' + modifier]
      };
    },
  },
  methods: {
    updateHoverState(isHover) {
      this.hoverState = isHover;
    }
  }
});

new Vue({
  el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.4/vue.min.js"></script>
<div id="app">
  <custom-button></custom-button>
</div>

<script type="text/template" id="custom-button">
  <button type="button" :style="styleObject" @mouseenter="updateHoverState(true)" @mouseleave="updateHoverState(false)" class="btn btn-outline-info large-button">
        {{ button.text }}
  </button>
</script>

【讨论】:

  • 这行得通,但感觉像是一种非常复杂的方法。如果:style 属性有修饰符就好了。
  • @EdShee 实际上,有 :) 如果您考虑使用 CSS 自定义属性和变量,这是完全可能的:并且无需绑定鼠标事件。我已经更新了我的答案以反映这种新的可能性。
【解决方案2】:

其他方式(使用 css 变量)。

您需要创建带有样式的 HTML

<style>
     div[vueid=${_uid}] { --btn-hover: ${`Here your hover brush`} }
</style>

并将其注入到您的组件中。

<template>
   <div vueid="_uid">
      <button></button>
      <div v-html="styleCode"></div>
   </div>
</template>

然后只需在静态css 文件中使用这个变量来设置按钮样式。

button:hover { background: var(--btn-hover); }

注意:您可以在:root选择器中描述默认变量值。

【讨论】:

    【解决方案3】:

    您可以为您的 Vuejs 组件分配一个 id 并在样式表中应用所需的悬停样式。

    <button id="styledButton" type="button"
    :style="{
    color:button.color,
        backgroundColor:button.colorBackd,
        borderColor:button.borderColor,
    }"
    class="btn btn-outline-info large-button">
    
        {{ button.text }}
    </button>
    

    然后在标签中,

    <style>
    styledButton:hover {
    color: #FFFFFF
    };
    </style>
    

    如果您希望悬停样式包含任何动态数据。制作一个调用计算属性的标签。

    <style>{{computedStyle}}</style>
    

    【讨论】:

      【解决方案4】:

      如果你使用单个文件组件,那么你只需要将按钮样式设置为作用域:

      <template>
          <button></button>
      </template>
      
      <style scoped>
          button {
              /* your button style here */
          }
      </style>
      

      甚至对于更受限的样式,也有模块,如下所示:How to correctly use "scoped" styles in VueJS single file components?

      【讨论】:

        【解决方案5】:

        看到这在 vue 中没有实现后,我决定使用叠加层,这加起来就是使用 :style 到叠加层,将通过更改不透明度来显示。

        基本上是:

        <div id="test" :style="style">
          <div class="overlay" :style="style.hover"></div>
        </div>
        

        var testArea = Vue.component('test-area', {
          template: '<div id="test" :style="style"><div class="overlay" :style="style.hover"></div></div>',
          computed: {
            style() {
              return {
                backgroundColor: '#0f0',
                hover: {
                  backgroundColor: '#f00'
                }
              };
            },
          }
        });
        
        new Vue({
          el: '#app'
        });
        #test {
          position: relative;
          width: 100px;
          height: 100px;
        }
        
        #test>.overlay {
          opacity: 0;
        }
        
        #test:hover>.overlay {
          width: 100%;
          height: 100%;
          position: absolute;
          opacity: 1;
        }
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
        <div id="app">
          <test-area></test-area>
        </div>

        【讨论】:

          【解决方案6】:

          我想更改悬停时的 z-index,以便悬停的 p 标签出现在顶部。为此,我必须监听事件以及一些值。

          <template>
          ...
          <p @mouseover="changeZIndex"
             @mouseleave="changeZIndexToOriginal({$event,old_z_index})
          >
          ...
          </template>
          
          
          <script>
          ...methods
          changeZIndex(e){
              //change to new z-index
              e.target.style.zIndex = 5 //to show on top
          }
          changeZIndexToOriginal(e){
              //e.$event is  an event which is trirgered. to get event along with some value we have to use this approach
              // e.old_z_index is z-index that I want to set back again. I am just using loop index to set z-index
              e.$event.target.style.zIndex = e.old_z_index
          }
          ...
          </script>
          

          使用上述方法,我们可以更改与目标元素相关的任何内容。

          【讨论】:

            【解决方案7】:

            我发现一个非常简单的解决方案是改用v-bind:class 指令:

            在我的情况下,当此元素处于非活动状态时,我需要添加悬停:

            :class="{'inactive': !item.count}"

            在这种情况下,我可以向我的类添加一个非活动属性,然后我可以简单地使用 hover 属性设置该类的样式,如下所示:

            .inactive {
              color: black;
            
              &:hover {
                background-color: green;   
              }
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2023-04-02
              • 2018-11-10
              • 2017-10-10
              • 1970-01-01
              • 1970-01-01
              • 2021-02-21
              • 2021-11-25
              • 2021-02-27
              相关资源
              最近更新 更多