【问题标题】:Dynamic styling for pseudo element's content in Vue2.xVue 2.x 中伪元素内容的动态样式
【发布时间】:2025-12-11 00:55:02
【问题描述】:

我有一个基本上是图标和工具提示的组件;它在鼠标悬停时显示工具提示(其文本来自父组件作为道具)。我在伪元素的帮助下实现了工具提示,所以我需要用道具的值更新伪元素的内容。我也知道 CSS 的伪元素规则不是 DOM 的一部分,因此无法使用 JavaScript 方法更改它们,但我发现了一堆基本上适用于任何 CSS 属性但不适用于 @ 987654321@(我可以看到它们有效(例如,对于工具提示的 width 属性或其颜色)但奇怪的是不适用于 content 属性),这是我到目前为止所做的,任何帮助将不胜感激:

<template>
    <div>
        <!-- <style>
            :root {
            --info-msg: {{tooltipContent}};
            }
        </style> -->
        <div class="infoBar">
            <svg-icon
                fill="#d5d5dc"
                :width="16"
                :height="16"
                name="common/c-info"
                class="infoBar__icon"
            />
        </div>
    </div>

</template>

<script>
export default {
  name: 'ContentInfo',
  props: {
    tooltipContent: {
      type: String,
      default: 'hint text goes here'
    }
  },
  mounted () {
    console.log(this.tooltipContent)
    this.applyCSS()
  },

  beforeUpdate () {
    this.applyCSS()
  },
  methods: {
    applyCSS () {
      const cssRule = `
      .infoBar:after{
        content: ${this.tooltipContent};
      }`
      const style = document.createElement('style')
      style.type = 'text/css'
      this.$el.appendChild(style)
      style.innerHTML = cssRule
    }
  }

}
</script>

<style lang="postcss" >

  .infoBar{
    position: relative;
    margin-left: 24px;
    &::after {
      background-color: #000;
      font-size: 12px;
      color: #fff;
      border-radius: 2px;
      width: 198px;
      height: 40px;
     /*content: var(--info-msg)*/
      display: none;
      padding: 11px 26px 10px 27px;
      position: absolute;
      top: 0;
      left: 80%;
      transform: translate(-50%, calc(-100% - 10px));
      z-index: 999;
    }
    &::before {
      background-color: #000;
      content: '';
      display: none;
      position: absolute;
      width: 10px;
      height: 6px;
      z-index: 999;
      top: 0;
      left: 80%;
      transform: translate(-50%, calc(-100% - 10px)) rotate(45deg);
    }
    &:hover::after {
      display: block;
    }
    &:hover::before {
      display: block;
    }
    &__icon:hover{
        fill: #e4002b;
      }
  }

  </style>

【问题讨论】:

    标签: javascript css vue.js vuejs2


    【解决方案1】:

    按照这些步骤,您可以将 css 中的 props 用作 css 变量:

    1. 在计算中使用 props 来返回一个 css 变量的对象并将这个对象绑定到组件的样式
    2. 你应该给组件一个类名,因为可以从 css 样式部分的类名中访问 c​​ss 变量
    3. 对于应该采用字符串格式才能正常工作的 css 变量,您应该使用 JSON.stringify()content css 属性就是这种情况)

    运行下面的示例并亲自查看,通过悬停显示的after 元素的颜色和文本都作为来自父组件的道具:

    Vue.component('pseudo', {
      data() {
        return {
          title: 'Hover me',
        }
      },
      props: {
        color: {
          type: String,
        },
        text: {
          type: String,
        }
      },
      computed: {
        cssVars() {
          return {
            '--color': this.color,
            '--text': JSON.stringify(this.text),
          }
        }
      },
      template: `<div class="content" :style="cssVars">{{title}}</div>`,
    });
    
    var vm = new Vue({
      el: '#app',
    });
    .content {
      color: red;
    }
    
    .content:hover::after {
      content: var(--text);
      color: var(--color);
      margin-left: 20px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
    <div id="app">
      <pseudo color="green" text="I'm from Prop!!"></pseudo>
    </div>

    【讨论】: