3

I want to dynamically change the background-image on a ccs class in an imported component How can I do that?

I have installed 'vue-range-slider' and have imported RangeSlider

The range-slider is set up the following way.

<template>
  <div id="slider_div" >

  <range-slider
      class="slider"
      min="0"
      max="100">
  </range-slider>

 </div>
</template>

<script>
import RangeSlider from 'vue-range-slider'
import 'vue-range-slider/dist/vue-range-slider.css';

export default {
  name: 'susScore',
  data: function() {
    return {
      emoji: "../assets/emoji_small.jpg",
    }
  },
  components: {
    RangeSlider
  }

</script>

<style >
#slider_div{
  margin-top: 95px;
  margin-left: 4%;
}

.slider{
  width:200px;
}

.range-slider-knob {
    background-image: url("../assets/emoji_small.jpg")
}

</style>

In this case I am sending a specific image but I want to send an image dynamically using the data option, emoji, in the component.

Question
How can I dynamically update the background-image in the imported .range-slider-knob class?

I tried using CSS variables in a previous question here on SO (Dynamically add image with css variable in vue) but got the reply that that wasn't possible

2 Answers 2

2

You can't use vm properties in <style> tag, but you can update emoji in data to:

emoji: require("../assets/emoji_small.jpg")

... and then pass it to any template element using:

<whatever :style={backgroundImage: `url(${emoji})`} />

A fully working example: codesanbox.

I combined require() with a computed changing loaded image based on slider value.

Sign up to request clarification or add additional context in comments.

13 Comments

Thanks. Sure I can use codesandbox but all the code in the component is in the question so I don't know what more I can add. Also how do you import 'vue-range-slider' and RangeSlider in codesandbox ? I tried adding the whatever div that you suggested but got (Syntax Error: SyntaxError: Unexpected token) when rendering. It seems that something is missing, or what can be the issue? Thanks
You import them the same way you import them in any node based environment. You install the package (look in left-bottom corner) and import whatever from 'whatever'. <whatever> is not to be used literally. It was a figure of speech, saying you could use it on either <div>s or <custom-element>s.
I have created a sandbox at the following link "codesandbox.io/live/rkGNK", everything works but when I added the suggested "div /whatever" the I got the following error "./src/sandbox/eval/transpilers/vue/template-compiler/loader.js"/r.default@codesandbox.io/static/js/…
codesandbox.io/s/empty-morning-pcoso?file=/src/components/… this is another sandbox link. Maybe it works better?
@user, if you're getting this in your project, setting "env": { "node": true } in your eslintrc.js (or in package.json > eslintConfig) should do it. If it's in codesandbox, just place /* global require */ at the top of the file (if it's a .js file) or at the top of the <script> tag if it's a .vue file, like I did in my sandbox. This comment tells eslint: "trust me, require is defined in global context". Because it is. It's defined in node. But eslint doesn't know it so it complains about it not being defined before it's used.
|
0

In the RangeSlider.vue file, line 13 shows that the component includes a named slot 'knob'. Vue Slots let you pass html/vue content into the component.

You could pass in a simple div on which you can dynamically change it's background using a method like @tao suggested. Note that a name attribute is given to match the name of the slot you are trying to replace; however, the name shouldn't be required because it is the only slot within component you are using.

<range-slider
   class="slider"
   min="0"
   max="100">
   <div
      name="knob"
      :style={backgroundImage: url(emoji)}
   />
</range-slider>

This method also gives you more freedom in how the knob is presented and/or manipulated with JS.

4 Comments

Thanks. I tried adding the div that you suggested but when rendering something seems to be missing. For example I get the error "Syntax Error: SyntaxError: Unexpected token". Should there be any citation marks or similar in the div? It seems that something is missing or?
Unless you declare it in computed: computed: { require: () => require }, require is not defined in vm context, so you can't use it in template. Basically, it has to be a property of this to be usable in template. See this answer.
Oh right... Well, the Vue loader should take care of a plain path anyway. On an additional note, I tried playing with the vue-range-slider in a small sandbox on my machine. I followed the documentation on overriding styles, nothing changed... And no changes occurred when I used a custom knob slot. Maybe the component is broken...
Ok, thanks. Regarding overriding styles it seems to work since I can change the image of the knob if I for example input background-image: url("../assets/emoji_small.jpg") in the range-slider-knob class as specified in the example. So I can change the image but it can't get it to work when using slots

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.