9

I have a Bootstrap Vue ProgressBar. I need to add to the class ".progress-bar" pseudo element :: after with content icon (from FontAwsome). And I also want it to be dynamic. Because I have implemented steps in my ProgressBar(from 0 tp 100) and i want, when i click, this icon will go with ProgressBar line.

<b-progress v-bind:style="styleProgressBar" :value="counter" :max="max"></b-progress>

 export default {
        components:{
            'navbar':navbar
        },
        name: "myPage",
        data() {
            return {
                counter: 0,
                max: 100,
                step:1,
            }
        },
        methods:{
            prev() {
                this.step--;
            },
            next() {
                this.step++;
                if (this.counter < 100) {
                    this.counter += 34;
                }
            }
        }
    }

I also saw this: https://v2.vuejs.org/v2/guide/class-and-style.html

<div v-bind:style="styleObject"></div>

data: {
  styleObject: {
    color: 'red',
    fontSize: '13px'
  }
}
tony19
  • 125,647
  • 18
  • 229
  • 307
Ivan Zavalinich
  • 167
  • 1
  • 1
  • 8

4 Answers4

9

Let's say you have a parent component:

<div id="parent">
  <ChildComponent id="child"> // Possibly from another library?
</div>

// renders ->

<div id="parent">
   <div id="child">
     <div id="child-component-item">
        ::after
     </div>
   </div>
</div>

The challenge is creating a binding for the #child-component-item:after selector.

We can use css vars to solve this problem, by "reaching into" the child component with some CSS. Note that you may have to use ::v-deep if your style is scoped.

parent-component.js

<div id="parent-component" :style="{'--bgColor': bgColor}">
   <ChildComponent>
</div>

<script>
  export default {
    data() {
      return {
        bgColor: 'red'
      }
    }
  }
</script>

<style>
   #child-component-item:after {
      background-color: var(--bgColor)
   }
</style>
nikk wong
  • 8,059
  • 6
  • 51
  • 68
6

Use css var()

And then :style="{ '--varName': xxx}"

Jadian
  • 4,144
  • 2
  • 13
  • 10
  • More similar approaches here: https://stackoverflow.com/questions/47322875/vue-js-dynamic-style-with-variables –  Apr 19 '21 at 13:40
0

I've had the same issue, but for ::before, and in combination with var(), url(), multiple ternary operators (my own case - you shouldn't need it), I was able to fix background-image in such a way:

template

<div :style="[
  case1 ? { '--iconUrl': `url(${require('../../../public/icon1.svg')})`} :
  case2 ? { '--iconUrl': `url(${require('../../../public/icon2.svg')})`} :
  { '--iconUrl': `url(${require('../../../public/default.svg')})` },
]" class="myClass">

styles

div.myClass::before {
  background-image: var(--iconUrl);
}

Edit: I didn't have to declare iconUrl in my data() -> return.

Daniel Danielecki
  • 8,508
  • 6
  • 68
  • 94
-1

It seems you'd like to add one icon following the progress bar.

If so, check below demo, it uses one span simulate the icon, then bind left to move the icon.

Vue.config.productionTip = false
app = new Vue({
  el: "#app",
  data: {
    counter: 0,
    max: 100,
    intervalID: null
  },
  methods: {
    runTask: function () {      
      clearInterval(this.intervalID)
      this.counter = 0
      this.intervalID = setInterval(() => {
        this.counter = (this.counter+7)%this.max
      }, 1000)
    }
  }
})
.badge {
  background-color:green;
  border: 1px solid black;
  padding: 2px;
  transition: 1s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.css"/>

<script src="//unpkg.com/babel-polyfill@latest/dist/polyfill.min.js"></script>
<script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.js"></script>
<div id="app">
  <button @click="runTask()">Run</button>
  <b-progress class="mt-1" :max="max" show-value>
     <b-progress-bar :value="counter" variant="success">
        <span class="badge" style="position:absolute;" :style="{'left':counter*100/max + '%'}" v-show="counter > 0">x</span>
     </b-progress-bar>
  </b-progress>
</div>
Sphinx
  • 10,519
  • 2
  • 27
  • 45
  • 2
    While a good answer, this doesn't OP's question about how to style a pseudo element. All this does is add an extra element and apply inline style to it. – Hybrid web dev Apr 30 '19 at 10:57