概要
为v-slot
增加简写语法
基础示例
<foo>
<template #header="{ msg }">
Message from header: {{ msg }}
</template>
<template #footer>
A static footer
</template>
</foo>
起因
简写就是一个名字需求,主要为了提供更简洁的语法
在Vue里我们仅为两个操作符:v-bind和v-on提供了简写语法
<div v-bind:id="id"></div>
<div :id="id"></div>
<button v-on:click="onClick"></button>
<button @click="onClick"></button>
v-bind
和 v-on
经常在同样的元素里被重复使用,当每个之间的信息差别不是指令参数而是指令本身的时候,会很冗长。
所以简写通过减少重复部分(v-xxx),着重不同的部分(参数),来提高信噪比。
新的v-slot
语法也可以解决多个slot的情况下同样的问题。
<TestComponent>
<template v-slot:one="{ name }">Hello {{ name }}</template>
<template v-slot:two="{ name }">Hello {{ name }}</template>
<template v-slot:three="{ name }">Hello {{name }}</template>
</TestComponent>
这里的v-slot
重复了非常多次,而真正不同的地方是slot的名字(有参数表示)
简写可以让slot
的名字表现的更简洁
<TestComponent>
<template #one="{ name }">Hello {{ name }}</template>
<template #two="{ name }">Hello {{ name }}</template>
<template #three="{ name }">Hello {{name }}</template>
</TestComponent>
细节设计
简写和 v-bind
v-on
的规则非常类似: 用简写符号(#)代替 指令名+冒号
<!-- full syntax -->
<foo>
<template v-slot:header="{ msg }">
Message from header: {{ msg }}
</template>
<template v-slot:footer>
A static footer
</template>
</foo>
<!-- shorthand -->
<foo>
<template #header="{ msg }">
Message from header: {{ msg }}
</template>
<template #footer>
A static footer
</template>
</foo>
和 v-bind
与 v-on
相似,简写仅在有参数的时候工作。也就意味着 v-slot
没有参数的时候不等于 #=
。对于默认插槽,v-slot
和 #default
都可以运行。
<foo v-slot="{ msg }">
{{ msg }}
</foo>
<foo #default="{ msg }">
{{ msg }}
</foo>
#
的选择是基于上一个RFC的反馈 进行的选择,它与css中的id选择器有相似之处,在概念上可以很好的转换为slot的名称。
举一些真实的例子
<Promised :promise="usersPromise">
<template #pending>
<p>Loading...</p>
</template>
<template #default="users">
<ul>
<li v-for="user in users">{{ user.name }}</li>
</ul>
</template>
<template #rejected="error">
<p>Error: {{ error.message }}</p>
</template>
</Promised>
缺点
一些人会争论说,slot并不是一个非常通用到需要提供缩写的功能,而且会导致初学者的学习曲线更复杂,结果是这样的:
- i. 我相信scoped slot对于第三方高可定制,可组合的组件库是非常重要的功能。我想我们希望看到更多的组件库在未来为了高可定制性,可组合性,而依赖slot。当用户使用这样的组件库的时候,缩写会更有价值(如示例所示)
- ii.速记的转换规则简单明了,与现有速记保持一致。如果用户了解了基本语法的工作原理,那么理解缩写只有一点点额外步骤。
选择
一些改变的标签在之前的的RFC被讨论过,一个类似的符号&
<foo>
<template &header="{ msg }">
Message from header: {{ msg }}
</template>
<template &footer>
A static footer
</template>
</foo>
采用策略
这应该是对v-slot
语法的自然扩展。理想情况下,我们想同时支持普通语法和缩写语法,让用户可以同时学习,晚一些采用缩写语法可能会让一些用户只知道v-slot
语法,并且在看到别人代码的时候很迷惑。