Vue: $slots elements are not rendered if it derived by computed prop

Created on 25 Aug 2016  路  6Comments  路  Source: vuejs/vue

Vue.js version

2.0.0-rc.3

Reproduction Link

https://jsfiddle.net/ktsn/oc8g5dcm/6/

Steps to reproduce

Click "Add List" button.

What is Expected?

Both test1 and test2 components render the elements passed to $slots.

What is actually happening?

The test2 renders the elements but test1 is not.

Note that we can avoid this issue if adding cache: false option for the computed option.

Most helpful comment

I ran into this problem and the solution to this one is simply using a getter method (i.e getSlots()) instead of hacks like adding a random property just so you can use a computed property and reference the said random property inside it.

Referencing OP's jsfiddle, instead of:

computed: {
  firstSlot() {
    return this.$slots.default
  }
}

do this:

methods: {
  getFirstSlot() {
    return this.$slots.default
  }
}

This solution applies to any other non-reactive properties and not only $slots

All 6 comments

The point is that $slots is not reactive (and it not meant to be as far as I know from Evan), so the computed prop will not re-evaluate when $slots change.

And I assume they change/get filled _after_ the computed props have been evaluated initially.

I would call this expected behaviour.

Ah, I think it's true, thanks!
But should we provide an error (or warning) message when using such values in computed getters?
It could be large pit fall for users...

That kind of warning would be hard to implement because there may be scenarios where someone uses $slots inside a computed property for a good reason, and only wants it to update when another, reactive value changes.

So Vue would have to check weither _only_ non-reactive elements are used, which is not worth it in my opinion.

We should rather make it clear in the guide and API docs that computed properties only react to changes references to data, props and other computed properties.

@chrisvfritz opinions?

Thanks for explaining, @LinusBorg!

I agree that implementing a warning probably isn't feasible and that we can make this more clear in the guide. I'll take care of it. 馃檪 I think in any use case where one's tempted to use $slots in a computed property though, moving that data to one or more props (which are reactive) would be a better solution.

I ran into this problem and the solution to this one is simply using a getter method (i.e getSlots()) instead of hacks like adding a random property just so you can use a computed property and reference the said random property inside it.

Referencing OP's jsfiddle, instead of:

computed: {
  firstSlot() {
    return this.$slots.default
  }
}

do this:

methods: {
  getFirstSlot() {
    return this.$slots.default
  }
}

This solution applies to any other non-reactive properties and not only $slots

Was this page helpful?
0 / 5 - 0 ratings

Related issues

6pm picture 6pm  路  3Comments

seemsindie picture seemsindie  路  3Comments

hiendv picture hiendv  路  3Comments

aviggngyv picture aviggngyv  路  3Comments

franciscolourenco picture franciscolourenco  路  3Comments