-
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
Render function API change #28
Conversation
render(
// declared props
props,
// resolved slots
slots,
// fallthrough attributes
attrs,
// the raw vnode in parent scope representing this component
vnode
) {} Is there a reason for passing 4 arguments instead of 1 object which dev could destruct?
|
@jacekkarczmarczyk One perk of positional arguments is easier type annotation. For object style argument, users have to annotate all property types. Positional arguments can be optionally skipped and only what users want to specify need be annotated. |
And how you skip position arguments? |
I think it's more about not allocating an extra object when rendering every component |
render({ propA, propB }) { /* ... */ }
vs
render({ props: { propA, propB } }) I guess the choice is obvious |
@jacekkarczmarczyk this is a carefully considered choice. These arguments are ordered from more commonly used to less commonly used. Most users will probably never use the 4th argument ( render(props) { /* ... */ }
render(props, slots) { /* ... */ } In these cases the perks mentioned by @HerringtonDarkholme and @Kelin2025 become more obvious. Plus there's the small perf benefits of avoiding an extra object and the destructuring. |
I'd like to present a point against the HTML event names are (AFAIK) casa-sensitive, and the automatic case conversion can affect Vue's perfect score on Custom Elements Everywhere benchmark. For example, what's the equivalent to |
This comment has been minimized.
This comment has been minimized.
@leopiccionia that's a good point - we actually need to consider this for component custom events as well. Maybe we can use the h('custom-element', {
// listens to "someevent"
onSomeEvent: e => {
},
// listenes to "SomeEvent"
'on:SomeEvent': e => {
// ...
}
}) |
Does that mean that we cannot add our own custom properties to a DOM node anymore, like vue does with We are currently using:
|
@rashfael interesting, I guess we need to keep escape hatches for all explicit binding types. How about: h('div', {
'attr:id': 'foo',
'prop:__ourSoftware__': { ... },
'on:click': () => { ... }
}) |
How to use escape hatches in template syntax? |
@znck The same as before? And for DOM props with even easier syntax: https://github.com/vuejs/rfcs/blob/v-bind-prop-shorthand/active-rfcs/0000-v-bind-prop-shorthand.md |
We should carefully evaluate the possible performance impact of having to match each prop name of each and every vnode against 3 RegExp's (or something similar), when these seemt to be edge cases. Techncially we can use custom directives to apply these things as well, right? Not nearly as ergonomic, of course ... |
@LinusBorg does it really have to run those regex patterns for every prop? It'd be faster to check if the string has a colon with a simple This way there's a very minimal cost to props not using a colon. |
Of course it doesn't have to be a regexp, which is why I wrote
To be honest I have no good intuition about the cost of these operations one way or another, it just seems wasteful to do this check for literally thousands and thousands of attributes in your app's virtual dom given we will likely have very few occurrences of these escape hatches. |
@LinusBorg Do you mean something like I don't know how custom directives are handled in diff algorithm. Would there be a performance penalty (in comparison to something like |
does this feature imply that you could render jsx inside templates? 😅 <template>
<div>
{{ h('h1', 'hello') }}
{{ <h1>hello</h1> }} <!-- would `h` be accessible here? -->
</div>
</template>
<script>
import { createElement as h } from 'vue'
export default {
data () { return { h } }
}
</script> |
This is nice but one small gripe - Personally I think this escape hatch API more sense: h('div', {
'attr:id': 'foo',
'prop:__ourSoftware__': { ... },
'event:click': () => { ... }
}) I.e.: - 'on:click': () => { ... }
+ 'event:click': () => { ... } ...despite that we use But I'm sure many will disagree. My reasoning is that the first two describe the what.
See what I mean? The counter-argument will be that the word |
This RFC is now in final comments stage. An RFC in final comments stage means that:
|
I don't have a good intuition about the performance impact of checking for the escape hatch prefixes either... but as a cheaper alternative perhaps these properties could be wrapped in an object, so most of the time the algorithm would only have to check for the existence of a single key: h('div', {
id: 'foo',
explicit: {
'attr:something': 'bar',
'prop:__ourSoftware__': { ... },
'on:Click': () => { ... }
}
}) |
@tobyzerner that's a good idea I think. We could use a Symbol as the key so we don't have to add another reserved prop name besides |
@yyx990803 There's a typo in the link in your first comment, should be |
Can It's pretty important for me, as a plugin author.
I understand |
like this: // skip props
render(_,slots){
} |
Rendered