-
Notifications
You must be signed in to change notification settings - Fork 546
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rfc-0013: Destructuring props #142
Comments
But you would have to use const greeting = computed(() => `Hello ${props.name}!`) vs const greeting = computed(() => `Hello ${name.value}!`) |
I know but I think it definitely outweighs the drawback of losing reactivity or having to use toRefs every time. I don't mind having to use |
When we designed this new API, we assumed that the majority of use cases would use Consequently, it would have been odd to make As we now have collected a lot of hands-on experience with the new API, it seems that this initial assumption was wrong: refs are required or at least more useful in a lot of situations, and much more often than we anticipated. So far that a lot of people, myself included, see refs as the default reactivity mechanism when working with the API and fall back to In light of that, having props defined as a plain object of refs would make more sense indeed. On the other hand, that only works if the list of properties on that object are static, as we would not be able to watch property additions / removals on a plain object of refs. But props can be undefined initially and passed with a value form the parent later. We might think: "ok, so let's pre-populate the But that also won't work, as we now support dynamic Props in Vue 3 - you can omit the That means we have no reliable way to predefine these properties on a plain |
@LinusBorg Thanks for the in-depth answer! My feeling as a new user is: why even have the "reactive" option? Why not only provide ref? That would alleviate a lot of confusion in my opinion and developers would be using the same patterns. So, I am happy to hear that you have come to the same conclusion basically. The big problem here with destructuring is that it is a silent error. You get no warning or anything. Reactivity has just disappeared without you knowing! Errors like that lead to huge headaches so I think they should be avoided at all costs. Also with all the recommendations of using "composition funcitons" like: const { x, y } = useMousePosition() ...then I gets really(!) confusing that things start to fail when you destructure props! The fact that ref props would not work with additions / removals is only a minor drawback. I don't remember ever having removed a property dynamically from props. The other reason you mention I don't fully understand. Maybe that feature could be left out? I hope you find some sort of solution. My personal dream scenario would be:
I don't have the insight you have to be able to pinpoint the drawbacks and what is possible and what is not. These are just my initial feelings as a new consumer of the compositional api :) |
I am pretty sure there will be linting rules that warns about destructing props. However, I still think it would be nicer if |
This was already true in Vue 2. It's just a more common to come across it in Vue 3. data() {
return {
myReactiveProperty: 'foo',
myReactiveObject: {
bar: 'baz'
}
}
},
provide() {
const { myReactiveProperty } = myReactiveProperty
const { bar } = this.myReactiveObject
return {
myContent: {
myReactiveProperty, // will not be reactive
bar, // will not be reactive
}
}
}, As Jason said, linters can help here. Also, note that this is independent of ref or reactive, basically. const ref1 = ref({ foo: 'bar' })
const { foo } = ref1.value // foo will not be reactive
const reactive1 = reactive({ foo: 'bar' })
const { foo } = reactive1 // foo will not be reactive The limitation is basically the same as this in pure JS: const obj1 = {foo: 'bar' }
const { foo } = obj1
obj1.foo = 'baz'
console.log(foo) // => still return 'bar' So it's rather a Javascript limitation than a Reactivity limitation. Refy only solve the problem when used within the object: const obj1 = {foo: ref('bar') }
const { foo } = obj1
obj1.foo.value = 'baz'
console.log(foo.value) // => 'baz' but then you can't have unwrapping. And I think realizing that, we can come up with hopefully relatively straightforward rules of thumb:
Furthermore, you say:
They might not be common for you but you're not the only user of Vue ;) And you also might be underestimating how often you might need it. Simple example: <myComponent v-if="user" :user="user" />
<myComponent v-else /> That's enough to break a plain props object as the Yes, you can work around it by inmitializing |
Ok, I understand that it is complex. Thanks a lot 👍 |
Update: prop destruction is now supported in |
Hi,
I am a big fan of the new Composition API and the wonderful typescript support and code reuse that comes with it. However, there are a couple of thing I don't quite understand yet.
I Vue2 it was easy and straightforward to create a computed property based on a prop:
And the intuitive way to do it in Vue3 would be:
However, this does not work because if we destructure props we lose reactivity! This was a bit of a gotcha for me 🙂
So "workarounds" would be either to aviod destructuring:
...or to use toRefs:
Now, my question is: why are props now passed in as refs to begin with? That would mean that we could use the "intuitive" code without having to remember not to destructure.
Thanks in advance! 🙂
The text was updated successfully, but these errors were encountered: