Skip to content

[Abandoned] RFC: Simplify scoped slot usage #9180

Closed
@yyx990803

Description

@yyx990803

This is a follow up of #7740 (comment)

Rational

Problems with current scoped slot usage:

  • Verbose if using <template slot-scope>
  • Limited to one element/component is using slot-scope directly on the slot element.

Proposal

Introduce a new v-scope directive, that can only be used on components:

<comp v-scope="scope">
  {{ scope.msg }}
</comp>

It would work the same as slot-scope for the default scoped slot for <comp> (with <comp> providing the scope value). So it also works with deconstructing:

<comp v-scope="{ msg }">
  {{ msg }}
</comp>

Why a New Directive

I believe the team briefly discussed what I proposed in #7740 (comment) on Slack some time back, but I could no longer find the chat record. Here's the reasoning behind a new directive:

  • slot-scope was introduced as a special attribute instead of a directive (attributes that start with v- prefix) because slot is an attribute, and we wanted to keep slot-related attributes consistent. slot was in turn introduced as a non-directive attribute because we want the usage to mirror the actual slot usage in the Shadow DOM standard. We figured it would be best to avoid having our own parallel v-slot when there's something that is conceptually the same in the standard.

  • Originally, slot-scope was designed to be only usable on <template> elements that act as abstract containers. But that was verbose - so we introduced the ability to use it directly on a slot element without the wrapping <template>. However, this also makes it impossible to allow using slot-scope directly on the component itself, because it would lead to ambiguity as illustrated here.

  • I thought about adding modifiers or special prefixes to slot-scope so that that we can use it on a component directly to indicate its slot content should be treated as the default scoped slot, but neither a modifier or a prefix like $ seem to be the right fit. The modifier by design should only be applied to directives, while new special syntax for a single use case is inconsistent with the whole syntax design.

  • For a very long time we've shied away from adding more directives, part of it being template syntax is something we want to keep as stable as possible, part of it being that we want to keep core directives to a minimum and only do things that users cannot easily do in userland. However, in this case scoped slot usage is important enough, and I think a new directive can be justified for making its usage significantly less noisy.

Concerns

  • The expression accepted by v-scope is different from most other directives: it expects a temporary variable name (which can also be a deconstruction), but not without a precedence: it acts just like the alias part of v-for. So conceptually v-scope falls into the same camp with v-for as a structural directive that creates temporary variables for its inner scope.

  • This would break the users code if the user has a custom directive named v-scope and is used on a component.

    • Since custom directives in v2 are primarily focused on direct DOM manipulations, it's relatively rare to see custom directives used on components, even more so for something that happens to be called v-scope, so the impact should be minimal.

    • Even in the case of it actually happening, it is straightforward to deal with by simply renaming the custom directive.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions