Vue新指令:v-slot
栏目: JavaScript · 发布时间: 5年前
内容简介:在有关于
slot
是Vue组件的一个重要机制,因为它使得完全解耦的组件之间可以灵活地被组合。在《Vue组件内容分发》和《Vue的作用域插槽》文章中我们深入的学习了 slot
怎么在Vue中的使用,但在Vue 3.0版本为 slot
引入了一套全新的模版语法。为了更好的从 2.x
过渡到 3.0
,Vue的 v2.6
版本引入了新的 slot
语法,即 v-slot
。接下来我们来学习新指令 v-slot
的使用。
v-slot
指令简介
在 v2.6
中,我们为具名插槽和作用域插槽引入了一个新的统一语法,即 v-slot
。它取代了 slot
和 slot-scope
这两个目前已被废弃但未被移除且仍在 文档 中的特性。这是一个较重大的改变,主要包含了:
-
v-slot
指令结合了slot
和slot-scope
的功能 -
scoped slots
的简写
有关于 v-slot
指令形成的讨论过程可以阅读 RFC-0001 和 RFC-0002 中的描述。
回顾 slot
的使用
从官网上我们可以获知,Vue中的 slot
主要分为: 单个插槽 、 具名插槽 和 作用域插槽 三种。而其使用也较为简单,比如我们有一个 SlotDemo
组件,可以在该组件中通过 <slot>
元素作为承载分发内容的出口:
<!-- SlotDemo.vue --> <template> <div class="slot"> <slot /> </div> </template> <script> export default { name: 'SlotDemo', } </script>
然后它允许你像下面这样使用 SlotDemo
组件,在使用该组件时,可以通过 <slot>
承载你想要的任何内容:
<!-- App.vue --> <SlotDemo> <div class="box"> <h1>Slot Demo</h1> <p>This is slot demo!</p> </div> </SlotDemo>
渲染出来的内容可以看出, div.box
中的内容替代了 <slot>
(也可以理解为该内容插入到了 slot
)中:
使用 slot
的时候,我们还可以为其设置一个默认的内容,也就是说没有提供内容的时候被渲染。比如下面这个 SubmitButton
组件中,默认情况下该按钮显示的文本内容是" 提交 ",这个时候可以在 <slot>
标签内设置其内容为“提交”:
<!-- SubmitButton.vue --> <template> <button> <slot>提交</slot> </button> </template> <script> export default { name: 'SubmitButton', } </script>
当我们引用 SubmitButton
并不给 slot
插入任何内容时:
<!-- App.vue --> <SubmitButton />
这个时候渲染出来的内容就是 slot
标签中的默认内容:
<button data-v-24449ecc="">提交</button>
如果我们想给按钮换成别的内容时,我们可以像下面这样使用:
<SubmitButton>保存</SubmitButton>
这个插入到 slot
中的内容“保存”会替代 slot
中默认的内容“提交”:
<button data-v-24449ecc="">保存</button>
最图如下图所示:
除了 单个插槽 之外,还可以使用 具名插槽 ,具名插槽的简单用法就是给 slot
显式的设置一个 name
值,比如下面这个 BaseLayout
组件:
<!-- BaseLayout.vue --> <template> <div class="container"> <header> <slot name="header">我们希望把页头放在这里~</slot> </header> <main> <slot>我们希望把主要内容放在这里</slot> </main> <footer> <slot name="footer">我们希望把页脚放在这里</slot> </footer> </div> </template> <script> export default { name: 'BaseLayout', } </script>
调用具名插槽时,在对应的标签上使用 slot="name"
,比如下面这个简单的用例:
<!-- App.vue --> <BaseLayout> <h1 slot="header">我是一个页头</h1> <p slot="footer">©w3cplus</p> </BaseLayout>
有关于Vue 2.6 版本之前 slot
更详细的使用可以阅读早前的学习笔记 《Vue组件内容分发》。
slot
还有另一个特性,那就是作用域插槽,用一个简单的示例来描述作用插槽的使用。先创建一个 ColorList
组件:
<!-- ColorList.vue --> <template> <div class="color-list"> <h2>{{ title }}</h2> <div class="list"> <div class="list-item" v-for="(item, index) in items" :key="index"> <slot v-bind="item"></slot> </div> </div> </div> </template> <script> export default { name: 'ColorList', props: { title: { type: String, default: 'Colors' }, items: { type: Array } } } </script> <!-- App.vue --> <template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <ColorList :items="colors" title="Colors"> <template scope="color"> <div :style="{background: color.hex}">{{ color.name }}</div> </template> </ColorList> </div> </template> <script> import ColorList from './components/ColorList' export default { name: 'app', components: { ColorList }, data () { return { colors: [ { name: 'Yellow', hex: '#F4D03F', }, { name: 'Green', hex: '#229954' }, { name: 'Purple', hex: '#9B59B6' } ] } } } </script>
有关于 Vue 2.6 之前作用域插槽更详细的介绍可以阅读早前整理的《Vue的作用域插槽》一文。
上面示例涉及到的Demo代码,可以从 [app-v-slot](//github.com/vuedemos/app-v-slot)
中的 step1
分支中获取。
v-slot
的使用
前面再次回顾了 Vue 2.6 版本之前的 slot
的使用,知道Vue中的 slot
主要有 单个插槽 、 具名插槽 和 作用域插槽 三种。在Vue 2.6版本起对 slot
有所更新,已经废弃了 slot
和 slot-scope
特性。从字面面上的理解就是Vue之后 slot
和 slot-scope
语法有所更改。自己在V3.0.1版本中亲测下面的使用( step1
也是基于该版本测试的),但接下来,主要看 v-slot
的使用。
同样先来看单个插槽,即 没有在 <slot>
标签中显式的设置 name
值 。比如 SlotDemo
这个组件:
<!-- SlotDemo.vue --> <template> <div class="slot-demo"> <slot>我是一个slot</slot> </div> </template>
正如前面所述, slot
标签中并没有显式设置 name
值,而且在 slot
标签中提供了一个默认的内容。我们在使用该组件时,可以通过 v-slot:default
来调用未显式设置 name
的 slot
:
<!-- App.vue --> <template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <SlotDemo /> <SlotDemo v-slot:default> <p>v-slot:default 的使用</p> </SlotDemo> </div> </template>
但一般建议 v-slot:default
添加到 <template>
上:
<!-- App.vue --> <SlotDemo> <template v-slot:default> <h3>v-slot:default</h3> </template> </SlotDemo>
同样能正常的渲染出我们预期的结果。
一个不带name的<slot>出口会带有隐含的名字default。
另外这里有一个特殊之处, 当被提供的内容只有默认的插槽时,组件的标签上才可以被当作插槽的模板来使用,也就是说 v-slot
可以直接使用在组件上 。正如上面的示例所示:
<SlotDemo v-slot:default> <p>v-slot:default 的使用</p> </SlotDemo>
接着来看一个具名插槽的示例,同样拿 BaseLayout
组件来举例:
<!-- BaseLayout.vue --> <template> <div class="container"> <header> <slot name="header">Header Content</slot> </header> <main> <slot>Main Content</slot> </main> <footer> <slot name="footer">Footer Content</slot> </footer> </div> </template> <script> export default { name: 'BaseLayout' } </script>
在 v2.6
之后使用也是采用 v-slot
:
<!-- V2.6版本之前 具名插槽的使用 --> <BaseLayout> <h1 slot="header">Vue 2.6之前具名插槽</h1> <p>我是页面的主内容</p> <p slot="footer">©w3cplus</p> </BaseLayout> <!-- V2.6之后 具名插槽的使用 --> <BaseLayout> <template v-slot:header> <h1>Vue 2.6之后具名插槽</h1> </template> <template v-slot:default> <p>我是页面的主内容</p> </template> <template v-slot:footer> <p>©w3cplus</p> </template> </BaseLayout>
在 <template>
元素中的所有内容都会被传入相应的插槽中。另外,没有任何被包裹在带有 v-slot
的 <template>
中的内容都会被视为默认插槽的内容。然而,为了使用更具规范或明确一些,仍然可以在一个 <template>
中包裹默认插槽的内容,同时使用 v-slot:default
来表示。
v-slot
和 v-on
和 v-bind
类似,也可以缩写,即 把参数之前的所有内容( v-slot:
)替换为字符 #
。例如,上面的示例我们可以改写成:
<BaseLayout> <template #header> <h1>Vue 2.6之后具名插槽</h1> </template> <template #default> <p>我是页面的主内容</p> </template> <template #footer> <p>©w3cplus</p> </template> </BaseLayout>
接下来,我们再一起来看看作用域插槽中怎么来使用 v-slot
。同样拿一个 List
组件来举例,并且它暴露了一个过滤后的列表数据作为它的作用域插槽。
<!-- List.vue --> <template> <div class="list"> <div class="item" v-for="(item, index) in items" :key="index"> <slot v-bind="item" /> </div> </div> </template> <script> export default { name: 'List', props: { items: { type: Array, } } } </script>
我们可以这样来调用 List
组件:
<!-- App.vue --> <!-- V2.6版本前 --> <List :items="colors"> <template slot-scope="color" slot="default"> <div :style="{backgroundColor: color.hex}"> {{ color.name }}</div> </template> </List> <!-- V2.6版本后 --> <List :items="colors" v-slot="color"> <div :style="{backgroundColor: color.hex}"> {{ color.name }}</div> </List> <script> import List from './components/List' export default { name: 'app', components: { List }, data () { return { colors: [ { name: 'Yellow', hex: '#F4D03F'}, { name: 'Green', hex: '#229954' }, { name: 'Purple', hex: '#9B59B6' } ] } } } </script>
从示例上的代码可以看出,使用 v-slot
,避免了额外的嵌套。另外 v-slot
指令也提供了一个绑定 slot
和 scope-slot
指令的方式,但需要使用一个 :
来分割它们。
有关于 v-slot
示例的相关代码,可以把分支切换到 step2
。
小结
在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot
指令)。它取代了 slot
和 slot-scope
这两个目前已被废弃但未被移除且仍在文档中的特性。这篇文章主要介绍了Vue中 slot
新老语法两个版本的使用。希望对大家有所帮助。有关于更详细的介绍可以阅读 Vue官网提供的教程 。
扩展阅读
- Vue插槽 (官网)
- Vue插槽废弃的语法
- New v-slot directive in Vue.js 2.6.0
- Vue 插槽新语法讨论过程: RFC-0001 和 RFC-0002
- Vue组件内容分发
- Vue的作用域插槽
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
汇编语言(第3版)
王爽 / 清华大学出版社 / 2013-9 / 36.00元
《汇编语言(第3版)》具有如下特点:采用了全新的结构对课程的内容进行组织,对知识进行最小化分割,为读者构造了循序渐进的学习线索;在深入本质的层面上对汇编语言进行讲解;对关键环节进行深入的剖析。《汇编语言(第3版)》可用作大学计算机专业本科生的汇编教材及希望深入学习计算机科学的读者的自学教材。一起来看看 《汇编语言(第3版)》 这本书的介绍吧!