-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
Passing data to Components is overly complicated - in common, simple examples #1987
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
Comments
Let's say parent components pass all its data implicitly into all children. Now all your child components implicitly make use of these parent scope variables. Later on:
Because |
First of all - thank you for the response. _Regarding #1 -_ closures could be applied here as well to grab the closest vue instance. _Yes,_ check the component chain. Brilliant. Then you could reference the properties of the vue instance directly. In my example above: pts and z. _Regarding #2 -_ Child component is expecting x, y, and z, it is tightly coupled to a source of this structure anyways, regardless of how the data got there or what it is named...therefore: Explicit data passing is only required when part of parent collections are named differently but have the same internal structure (x, y, z) - an unusual design. And in this scenario, you could still pass data explicitly. Win-win. I would also like to note that I was forced to abandon templates and inject templates with jquery because _I actually just could not get it to work due to syntax._ I wanted to pass the entire 'd' object into my template ...just couldn't figure it out from the documentation. _Would be awesome if this worked:_
_Or even better:_ http://es6-features.org/#PropertyShorthand
|
Vue.js is a sophisticated framework that uses established principles from other established libraries and framework. It's unlikely (and undesirable!) that it's throwing away its core principles due to your argumentation, so I don't really know what you're aiming for. Why don't you provide a jsfiddle, so we can try to help you in your specific use case that didn't work out for you? :) |
Here are a few things that needed to be fixed:
Working fiddle: https://jsfiddle.net/2rv60f4q/2/ |
Evan - thanks. #3 is probably not your fault and not a big deal... Regarding #2:Is there any way to make the template system transparent (optionally)? To just pass through all data as props automatically all the way down through the component when: 1? The data is declared Compare this component-less example to your fiddle: Component-less: https://jsfiddle.net/p98serxm/ Look how simple it is! Notice how I don't need these redundancies:
Why I think this is important: When I first discovered Vue I was in shock, because of the simplicity of its design. Everything is _meticulously_ simple (without sacrificing any functionality). It literally could not be any cleaner if you tried - and that's beautiful. However: Doing in a component what a standard Vue instance can do requires 2 extra declarations and 1 extra abstraction in the way I pass data. That's not simple. I know there is great abstraction here - and reason for it - but often we don't need it - and Vue usually isn't the right place to do these abstraction (my opinion). Many times I just wan't the template to function in the exact way that the Vue instance functions - as if there was no template at all...which brings me to #1. Regarding #1:I don't ever pass data like this:
In my opinion it shouldn't even be Vue's job to worry about this. I let Vue work on complex objects and package, name, alias the object however I want first.
Root access: Obviously I need to be able to access the root data in props and the html. Not letting me access the root object in props and subsequently the html is doing a major disservice to your component system - because I have to use an expanded syntax. Why: This combined with your props system makes the component system significantly more complicated than it needs to be - which goes against the reasons I chose Vue in the first place. Solution: I am going to continue to use Vue but to be honest it is cleaner for me to inject that html manually and not have to worry about passing data around in the component system. Please consider if a feature like this is something you think would benefit your framework in the future. Thanks for the help! |
Component is the boundary for simplicity. The whole point of components is so that you break your code into logically isolated units. If you feel it's redundant to pass data then you are probably using components prematurely when you don't actually need it. Remember Vue is not just for simple stuff. When you focus on "how simple it is", you probably don't realize the maintainability issues this will give rise to in large applications. Re how to pass data: you are missing the point. The point is the var d = {
a: 123
}
new Vue({
el: '#id',
data: d
}) There's no way Vue can tell the original object has a variable name of |
"Vue needs to know the property name in order to reference to them in templates." Yes "There's no way Vue can tell the original object has a variable name of d. You can only access a in your templates, because that is the top level property the Vue instance ever sees." But I don't need to know/care what the variable name is "Remember Vue is not just for simple stuff. " Of course not, Vue is great at making complicated stuff simple - that's the best thing about Vue. I am not saying that Vue should pass all data down automatically, I am just saying that I should have the option to do that. |
All of the above options reduce reusability of your components to some extent. |
Solutions:abcd: http://jsfiddle.net/rfn3hxrc/3/ Html
JS
By using the template system I can access all the data. "you are missing the point" ^ nail on the head |
Sorry late chimer... I see what FEA5T is saying... what none of you are saying though is... the loss of DRY by repeating data declarations props etc... is a small violation considering the benefits, modularity, re-usability etc. I think FEA5T gets it, however, this rant may just be so the rest of us can admit to our awe in FEA5T's brilliance. So I will say it, You FEA5T are indeed smarter than the teams of people developing frameworks, Vue included. May we get your resume? |
How to pass bulk of events elegantly? Let's say, to build a vue component called <template>
<button @mouseover="handleMouseOver" @mousemove="handleMouseMove" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @keydown="handleKeyDown" .....></button>
</template> Besides, deriving the <template>
<v-button @mouseover="handleMouseOver" @mousemove="handleMouseMove" @mousedown="handleMouseDown" @mouseup="handleMouseUp" @keydown="handleKeyDown" .....></v-button>
</template> Now, it seems that the only way to implement |
Yo FEA5T - try this solution. If I interpreted your desires correctly, you want a solution that has all the following traits... Creates no dependencies on parent components. Simple solution - does not even require vue. Here it is... Create a data model in its own .js and export it. Import this data model in whatever components you want to use it. Use it. The other answer is a question - why are you using vue? Just go back to regular javascript, declare a and b in page scope and access them exactly like you want. |
This issue is over two-year old, has been closed for quite some time, and doesn't even apply to the current state of Vue... |
@simplesmiler Thanks for the excellent advice In revisiting this issue 2 years wiser, I think that there was a legitimate use case I presented here: passing data from a parent component to any (possibly deep) child. The reason I complained about the prop syntax is because: Passing 5 children deep results in a ridiculous amount of code repetition.I believe I caught this a long time ago and it has taken a long time for provide/inject to address this use case (and they still don't fully address it).
Sound's a lot like closures in JS. This sounds great. So why not do this? Well, you said:
Well, turns out a component is logically isolated whether or not it is using props or closures. At runtime, the parent context must provide a required attribute:
Regardless of passing method, the required attribute must exist in parent scope. So that's not a good reason, because these methods all have the same logical isolation at runtime. My question is, do these input's need to be declared twice in a component, both in props and in the code? Why can't props be inferred from the code, like closures in JS?When I want declarative input, I have that: through props (parameters) . If I want inferred input, I should have that in a convenient and familiar way, like closures provide in JS. Why is this decision being made for me? Ultimately I understand, performance is king, Vue prevents you from shooting your feet off, which is why Vuex (inject global state), provide/inject (selectively inject some state) and the this.$parent (dangerous walk the chain yourself) options exist to carefully limit and select what must be passed down. Regarding @jochantrelle (don't be a jerk)
What I now find ironic now is, my requested solution was implement (differently) with provide/inject which were introduced in Vue 2.2. Let me quote:
Well:
Looks like I came out on the right side of this. Regarding decoupling:
No it doesn't. If a component need's a prop The real difference is in declarative vs implied, not decouplingWell, sometimes, we want declarative props, and sometimes we don't. Why doesn't Vue give dev's "sharp knives" to let them use the right tool for the job? Like JS does... I would even further argue that provide and inject are my solution, but with unfortunately even tighter coupling of parents to children than I wanted, because the parent has to explicitly declare what it is providing. In a closure scenario, the child is free to reference parent data without the parent knowing. This is a cleaner, less dependent (and admittedly poorly performing) solution. The key here is that a child says "I need this.myAttr", and if I don't have it, walk the chain until you find it. Regarding Modularity/Re-usability:
Except modularity and re-usability aren't lost. The dependency on The only reason not to do this is performance, and dev's should have the option:
So that all my components don't need to start like this:
Solution: Better provide/injectAny attribute that a component uses that isn't a func, data attr, computed, etc should automatically be added to the props list at runtime, and if that prop is not passed by a parent and Alternatively, a more powerful inject and provide should be avaliable.
or just a better provide/inject syntax:
|
Setup
Instance
Why do I have to pass data down in my html elem? Why doesn't it have access to the Vue instance that it is a child of like normal html would?
So that I can do this:
The text was updated successfully, but these errors were encountered: