2

So I thought I understood computed properties well and have been using them frequently, but I'm in a situation where I don't understand why there's no reactivity happening.

I'm trying to use the computed property to access and return a string, which is an image URL, from an array of URLs.

data() {
    return {
        Image1: 'placeholder'
    };
},
computed: {
    ImageTest() {
        if (this.ImageStyleSources.length !== 0) {
            this.Image1 = 'url(' + this.ImageStyleSources[1] + ')'
        } else {}
    }
}

The console.log is showing that the string (this.ImageStyleSources[1] -- from a mixin) is exactly what it should be, and the encapsulating 'url(' + ... + ')' is matching the CSS background-image value perfectly.

When I replace the data variable with the string it represents, everything works fine. So I know it's not the string itself that's the issue, and more the updating of the computed property.

On a possibly related note, there is an issue (presumably with vue-devtools) where there are duplicate components showing. When looking into these components, one set is updated exactly as it should be. The other is stuck on it's original return value for the property.

For extra clarity:

The condition, (this.ImageStyleSources.length !==0), is also timing as expected, as it determines that the array has been updated from it's empty placeholder. I've also tried using boolean vue data instead of this method for marking the point of the updated array.

Using vue-fela to update the background-image: but tried dynamic :style (with both string and object syntaxes) as well as other other css-in-js solutions besides fela, thinking they were the cause of the reactivity issue... but it seems that isn't the case.

Question: Are there known reactivity problems when using mixins? this.ImageStyleSources is in an imported mixin.

Another question: Does anyone have any idea what to do with this?

I'm almost embarrassed to say I've spent over two days repeatedly running into the same wall, so thanks for reading. : )

B

EDIT:

I've tried to use the computed property to return the value, instead of updating the data property:

// Computed
ImageTest() {
    if (this.ImageStyleSources.length !== 0) {
        return 'url(' + this.ImageStyleSources[1] + ')'
    } else {}
}

I've also tried using a watcher to update the data, instead:

watch: {
    ImageStyleSources: function () {
        if (this.ImageStyleSources.length !== 0) {
            this.Image1 = 'url(' + this.ImageStyleSources[1] + ')'
        } else {}
    }
},

Also tried calling a method in the mixin -- just after the array is updated and usable -- instead of using a condition.

...but I'm having the same experience, no matter what method I used to apply it (dynamic :style tag or css-in-js). The element's background simply won't update from the data property's placeholder string, or if not using data, it won't update with the returned string at all.

6
  • Computed properties should return a value. They should definitely not be manipulating values of data properties. That's a good way to get into an infinite loop Commented Aug 9, 2019 at 2:02
  • Because you have no return statements in your computed property, it's difficult to understand what you're trying to do here. How does the Image1 data property come into this? Where are you using this computed property? What are the expected results given different values of ImageStyleSources? Commented Aug 9, 2019 at 2:08
  • Computed properties are getters - if you dont get them they will not calculate. Its fine to let them return undefined or skip any return statement. Commented Aug 9, 2019 at 6:45
  • Sorry for the confusion. After multiple days I forgot to include that I've indeed tried using a watcher as an alternative, and also tried returning with the computed property as you can see in the edit above. I appreciate the clarity on how computed properties work. I've already learned something : ) However, my problem persists. Any further ideas? Commented Aug 9, 2019 at 18:03
  • I'm having trouble coming up with a way to accurately reproduce the issue in a codesandbox. And the Github repo exceeds the 250 module importing limit. : / Commented Aug 9, 2019 at 18:23

1 Answer 1

1

This should be a watcher:

watch: {
    imageStyleSources: function (source) {
         if (source.length) {
             this.Image1 = 'url(' + source[1] + ')'
         }
    }
}

Computed getters should return a value, and watchers are just generic reactive property observers where you can make some modifications and exit out of.

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

1 Comment

I've tried using a watcher instead, as you can see in the edit above. Apologies for not mentioning.

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.