8000 Merge pull request #3 from vuejs/slot-shorthand · vuejs/rfcs@d589e68 · GitHub
[go: up one dir, main page]

Skip to content

Commit d589e68

Browse files
authored
Merge pull request #3 from vuejs/slot-shorthand
Proposal for v-slot syntax shorthand
2 parents 3269c3c + 97fe0b6 commit d589e68

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
- Start Date: 01-16-2019
2+
- Target Major Version: (2.x / 3.x)
3+
- Reference Issues: https://github.com/vuejs/rfcs/pull/2
4+
- Implementation PR: (leave this empty)
5+
6+
# Summary
7+
8+
Add shorthand syntax for the `v-slot` syntax proposed in [rfc-0001](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0001-new-slot-syntax.md). Please make sure to read it first to get proper context for this proposal.
9+
10+
# Basic example
11+
12+
``` html
13+
<foo>
14+
<template #header="{ msg }">
15+
Message from header: {{ msg }}
16+
</template>
17+
18+
<template #footer>
19+
A static footer
20+
</template>
21+
</foo>
22+
```
23+
24+
# Motivation
25+
26+
A shorthand, as the name entails, primarily aims to provide more succinct syntax.
27+
28+
In Vue we currently provide shorthands only for two directives: `v-bind` and `v-on`:
29+
30+
``` html
31+
<div v-bind:id="id"></div>
32+
<div :id="id"></div>
33+
34+
<button v-on:click="onClick"></button>
35+
<button @click="onClick"></button>
36+
```
37+
38+
`v-bind` and `v-on` often get used repeatedly on the same element, and can get verbose when the information differing between each is **the directive argument** instead of the directive itself. **Shorthands thus help improve the signal/noise ratio by shortening the parts that are duplicated (`v-xxx`) and highlighting the parts that are different (the arguments).**
39+
40+
The new `v-slot` syntax can also get the same problem in components that expect multiple slots:
41+
42+
``` html
43+
<TestComponent>
44+
<template v-slot:one="{ name }">Hello {{ name }}</template>
45+
<template v-slot:two="{ name }">Hello {{ name }}</template>
46+
<template v-slot:three="{ name }">Hello {{name }}</template>
47+
</TestComponent>
48+
```
49+
50+
Here `v-slot` is repeated multiple times where the actual differing part is the slot name (denoted by the argument).
51+
52+
The shorthand helps slot names to be more easily scan-able:
53+
54+
``` html
55+
<TestComponent>
56+
<template #one="{ name }">Hello {{ name }}</template>
57+
<template #two="{ name }">Hello {{ name }}</template>
58+
<template #three="{ name }">Hello {{name }}</template>
59+
</TestComponent>
60+
```
61+
62+
# Detailed design
63+
64+
The shorthand follows very similar rules to the shorthand of `v-bind` and `v-on`: replace the directive name plus the colon with the shorthand symbol (`#`).
65+
66+
``` html
67+
<!-- full syntax -->
68+
<foo>
69+
<template v-slot:header="{ msg }">
70+
Message from header: {{ msg }}
71+
</template>
72+
73+
<template v-slot:footer>
74+
A static footer
75+
</template>
76+
</foo>
77+
78+
<!-- shorthand -->
79+
<foo>
80+
<template #header="{ msg }">
81+
Message from header: {{ msg }}
82+
</template>
83+
84+
<template #footer>
85+
A static footer
86+
</template>
87+
</foo>
88+
```
89+
90+
**Similar to `v-bind` and `v-on`, the shorthand only works when an argument is present. This means `v-slot` without an argument cannot be simplified to `#=`.** For default slots, either the full syntax (`v-slot`) or an explicit name (`#default`) should be used.
91+
92+
``` html
93+
<foo v-slot="{ msg }">
94+
{{ msg }}
95+
</foo>
96+
97+
<foo #default="{ msg }">
98+
{{ msg }}
99+
</foo>
100+
```
101+
102+
The choice of `#` is a selection based on the feedback collected in the previous RFC. It holds a resemblance to the id selector in CSS and translates quite well conceptually to stand for a slot's name.
103+
104+
Some example usage in a real-world library that relies on scoped slots ([vue-promised](https://github.com/posva/vue-promised)):
105+
106+
``` html
107+
<Promised :promise="usersPromise">
108+
<template #pending>
109+
<p>Loading...</p>
110+
</template>
111+
112+
<template #default="users">
113+
<ul>
114+
<li v-for="user in users">{{ user.name }}</li>
115+
</ul>
116+
</template>
117+
118+
<template #rejected="error">
119+
<p>Error: {{ error.message }}</p>
120+
</template>
121+
</Promised>
122+
```
123+
124+
# Drawbacks
125+
126+
- Some may argue that slots are not that commonly used and therefore don't really need a shorthand, and it could result in extra learning curve for beginners. In response to that:
127+
128+
1. I believe scoped slot is an important mechanism for building 3rd party component suites that are highly customizable and composable. I think we will see more component libraries relying on slots for customization and composition in the future. For a user using such a component library, a shorthand will become quite valuable (as demonstrated in the examples).
129+
130+
2. The translation rules for the shorthand is straightforward and consistent with existing shorthands. If the user learns how the base syntax works, understanding the shorthand is a minimal extra step.
131+
132+
# Alternatives
133+
134+
Some alternative symbols have been presented and discussed in the previous RFC. The only other one with similarly positive interest is `&`:
135+
136+
``` html
137+
<foo>
138+
<template &header="{ msg }">
139+
Message from header: {{ msg }}
140+
</template>
141+
142+
<template &footer>
143+
A static footer
144+
</template>
145+
</foo>
146+
```
147+
148+
# Adoption strategy
149+
150+
This should be a natural extension on top of the new `v-slot` syntax. Ideally, we'd want introduce the base syntax and the shorthand at the same time so users learn both at the same time. Introducing the shorthand at a later time runs the risk of some users only aware of the `v-slot` syntax and get confused when seeing the shorthand in others' code.
151+
152+
# Unresolved questions
153+
154+
N/A

0 commit comments

Comments
 (0)
0