user3130415
user3130415

Reputation: 363

Vuejs deep nested computed properties

I'm not really understanding where to put function() { return {} } and where not to when it comes to deeply nesting computed properties.

By the way, this is in a component!

computed: {
        styles: function() {
            return {
                slider: function() {
                    return {
                        height: {
                            cache: false,
                            get: function() {
                                return 'auto';
                            }
                        },
                        width: {
                            cache: false,
                            get: function() {
                                return $('#slideshow').width();
                            }
                        }
                    }
                }
            }
        }
    },

This is returning undefined. When I get rid of the function() { return {} } inside of the slider index, it returns an object when I do styles.slider.width instead of the get() return. It just shows an object with cache and get as indexes..

Thanks for any help!

The reason I'm asking is because I have multiple nested components that involve styling from the parent. Slider, tabs, carousels, etc. So I wanted to organize them like this.

Upvotes: 5

Views: 22732

Answers (2)

Valentine Shi
Valentine Shi

Reputation: 7800

As per 2020 and Vue 2.6.12 this is completelly possible. I believe this has been possible since v.2 but cannot confirm.

Here is the working example:

this.computed = {

    // One level deep nested, 
    // get these at `iscomplete.experience` 
    // or `iscomplete.volume`
    iscomplete: function() {
        return {
            experience: this.$data.experience !== null,
            volume: this.$data.volume > 100,
            // etc like this
        };
    },

    // More levels deep nested.
    // Get these at `istemp.value.v1 and `istemp.value.v2`
    istemp: function() {
        return {
            value1: {
                v1: this.$data.experience,
                v2: 'constant'
            }
        }
    }
    
};

As a result you will be able to access your deep nested computed in your template as e.g. follows <span v-text="iscomplete.experience"></span> that will output <span>true</span> for the first example computed above.

Note that:

  1. Since Vue v.2 cache key is deprecated;
  2. Vue would not execute functions assigned to a computed object nested keys;
  3. You cannot have computed for non-Vue-reactive things which in your case is e.g. $('#slideshow').width(). This means they are not going to be re-computed on their content change in this case (which is a computed's sole purpose). Hence these should be taken away from computed key.

Other than that I find nested computeds to be quite helpful sometimes to keep things in better order.

Upvotes: 0

Screll
Screll

Reputation: 286

I believe you mean to return a computed object, but not actually structure the computation in a nested manner?

What the others have said regarding the 'computed' hook not having syntax for nesting is correct, you will likely need to structure it differently.

This may work for you: I generate many objects in a similar fashion.

computed: {
   computedStyles(){
     var style = {slider:{}}
     style.slider.height = 'auto'
     style.slider.width = this.computedSlideshowWidth
     return style
   },
   computedSlideshowWidth(){
     return $('#slideshow').width()    
   }

Upvotes: 1

Related Questions