From 23757cc4c0ab61bc73efcfb5b533dc1041be61ef Mon Sep 17 00:00:00 2001 From: Alejandro Fernandez Date: Sun, 3 Feb 2019 17:59:16 +0100 Subject: [PATCH 1/3] Initial "Forwarding Events" Draft --- active-rfcs/0000-forwarding-events.md | 163 ++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 active-rfcs/0000-forwarding-events.md diff --git a/active-rfcs/0000-forwarding-events.md b/active-rfcs/0000-forwarding-events.md new file mode 100644 index 00000000..1c1095ed --- /dev/null +++ b/active-rfcs/0000-forwarding-events.md @@ -0,0 +1,163 @@ +- Start Date: 2019-02-03 +- Target Major Version: 2.x +- Reference Issues: N/A +- Implementation PR: + +# Summary + +Allow *re-emitting* (forwarding) an event that is not intended to be handled in the current component but we want to forward the children event behaviour to a grandparent component. + +This RFC helps reducing boilerplate for a common vue.js pattern. + +Introducing the new `.emit` event modifier. (Name opened to change/discussion) + +# Basic example + +This would be a good case where we could apply this new modifier: + +```html + +
+ +
+ + +
+ +
+ + +
+ +
+``` + +In above example, `parent-component` does not want/need to handle or add extra behaviour to _click_ event, but it wants to _re-emit_ the event upwards to allow parent components to handle it. + +# More realistic example + +Let's imagine we are building a custom text input. If we want to allow to react to common input events (focus, blur, etc...) we have to handle all the desired events and just _re-emit_ all the events (For the sake of the example, we won't add any custom behaviour to them): + +```html + +
+ +
+``` + +With the `.emit` modifier this could be simplified as: + +```html + +
+ +
+ + +
+ +
+``` + +# Motivation + +The main goal of this feature is to reduce boilerplate when building deeply nested components in which you have to emit events upwards through several component layers. + +If we make this process easier, this could help to avoid less visual patterns like `provide/inject`, or a custom event bus. + +# Detailed design + +This RFC is meant to be _only_ syntax sugar for this pattern: + +```html + + + + + +``` + +The new modifier could be chained with the rest of the modifiers too: + +```html + +
...
+ + +
...
+``` + +```html + + + + + +``` + +#### Templating engine +Currently, it is not allowed to create a handler without a value (`@click`). So the template compiler has to be modified in order to allow empty values when `.emit` modifier is present. + +Another thing to take into consideration is the opposite. I think it doesn't make sense to have a handler with the `.emit` modifier (`@click.emit="onClick"`). Maybe a warning indicating that `.emit` modifier is meant to avoid handling the event in the current component is enough. + +#### Render Function +For this case, I'd say that `.emit` doesn't need to be implemented in any way because of the nature of the render function. + +I'd leave to the user to implement it as the docs say for `.stop` or `.prevent`. + +# Drawbacks + +##### Another modifier +It's something "new" to learn and could confuse the newcomers. + +##### It's a less explicit way of emitting an event +Although I think the `.emit` modifier is a readable way of re-emitting an event, I understand that anyone could see this as a way of obfuscating what is happening. + +##### The relation with the rest of modifiers +Vue has more modifiers as _key modifiers_, _mouse modifiers_, _system modifiers_, etc... In some edge cases could be confusing because of the verbosity. + +```html + + + + + + + + + Date: Mon, 4 Feb 2019 10:51:12 +0100 Subject: [PATCH 2/3] Update forwarding-events RFC. --- active-rfcs/0000-forwarding-events.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/active-rfcs/0000-forwarding-events.md b/active-rfcs/0000-forwarding-events.md index 1c1095ed..ee7a8be5 100644 --- a/active-rfcs/0000-forwarding-events.md +++ b/active-rfcs/0000-forwarding-events.md @@ -108,21 +108,19 @@ The new modifier could be chained with the rest of the modifiers too: ``` #### Templating engine -Currently, it is not allowed to create a handler without a value (`@click`). So the template compiler has to be modified in order to allow empty values when `.emit` modifier is present. - -Another thing to take into consideration is the opposite. I think it doesn't make sense to have a handler with the `.emit` modifier (`@click.emit="onClick"`). Maybe a warning indicating that `.emit` modifier is meant to avoid handling the event in the current component is enough. +I think it doesn't make sense to have a handler with the `.emit` modifier (`@click.emit="onClick"`). Maybe a warning indicating that `.emit` modifier is meant to avoid handling the event in the current component is enough. #### Render Function For this case, I'd say that `.emit` doesn't need to be implemented in any way because of the nature of the render function. -I'd leave to the user to implement it as the docs say for `.stop` or `.prevent`. +I'd leave to the user to implement it as the docs say for `.stop` or `.prevent` modifiers. # Drawbacks ##### Another modifier It's something "new" to learn and could confuse the newcomers. -##### It's a less explicit way of emitting an event +##### It's less explicit Although I think the `.emit` modifier is a readable way of re-emitting an event, I understand that anyone could see this as a way of obfuscating what is happening. ##### The relation with the rest of modifiers @@ -154,6 +152,9 @@ The strategy is simple. This RFC only adds a feature on top of Vue, so it only n # Unresolved questions +##### Template handlers without value +I'm not really sure if the template engine allows to have handlers without value. I know that `@click.stop` works because I have used it a few times, but I don't know if it's an exception. I'd need any with more expertise to answer this question. + ##### Alternative names of the modifier I think the word `emit` makes sense, especially in Vue ecosystem. It's a known word and it's a known behaviour. The word `emit` is directly related to the events, so putting it next to an event handler, makes clear what the component it's trying to do. (`@click.emit`) From fa4013734eea67e03683c1cce66ffcadadd51eaa Mon Sep 17 00:00:00 2001 From: Alejandro Fernandez Date: Mon, 4 Feb 2019 11:31:40 +0100 Subject: [PATCH 3/3] Update "Forwarding Events" RFC --- active-rfcs/0000-forwarding-events.md | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/active-rfcs/0000-forwarding-events.md b/active-rfcs/0000-forwarding-events.md index ee7a8be5..fb63be16 100644 --- a/active-rfcs/0000-forwarding-events.md +++ b/active-rfcs/0000-forwarding-events.md @@ -107,23 +107,23 @@ The new modifier could be chained with the rest of the modifiers too: ``` -#### Templating engine -I think it doesn't make sense to have a handler with the `.emit` modifier (`@click.emit="onClick"`). Maybe a warning indicating that `.emit` modifier is meant to avoid handling the event in the current component is enough. +Things to take into consideration when implementing: -#### Render Function -For this case, I'd say that `.emit` doesn't need to be implemented in any way because of the nature of the render function. +1. At first sight, It doesn't make sense to have a handler with the `.emit` modifier (`@click.emit="onClick"`). Vue should throw a warning indicating that `.emit` modifier is meant to avoid handling the event in the current component and should not receive a value. -I'd leave to the user to implement it as the docs say for `.stop` or `.prevent` modifiers. +1. The order of the modifiers matters in this case. Check [Chaining with the rest of modifiers](https://github.com/Aferz/rfcs/blob/master/active-rfcs/0000-forwarding-events.md#the-relation-with-the-rest-of-modifiers) in Drawbacks section. + +1. Render function shouldn't be directly affected, but I'd reflect in the docs this is a modifier to implement in userland (Exactly as `.stop` or `.prevent` modifiers). # Drawbacks ##### Another modifier -It's something "new" to learn and could confuse the newcomers. +It's not really a new concept and it's totally optional but it's something new to learn. ##### It's less explicit Although I think the `.emit` modifier is a readable way of re-emitting an event, I understand that anyone could see this as a way of obfuscating what is happening. -##### The relation with the rest of modifiers +##### Chaining with the rest of modifiers Vue has more modifiers as _key modifiers_, _mouse modifiers_, _system modifiers_, etc... In some edge cases could be confusing because of the verbosity. ```html @@ -142,6 +142,18 @@ Vue has more modifiers as _key modifiers_, _mouse modifiers_, _system modifiers_ + + + + +``` + +This is something could be avoided with a warning, indicating if `.emit` is used, it should be used the last one. The Vue docs already reflect that the order of the modifiers matter, but this might be a very special case. + # Alternatives If this RFC is rejected, the alternative is to keep things as is right now.