一、插槽是什么

下面看一个例子
写一个父组件: test.vue

<template><div><div>我是父组件</div><myslot><p>测试这里内容的能否显示</p></myslot></div>
</template>
<script>import myslot from './myslot';  export default {components: {myslot}}
</script>

写一个子组件:myslot.vue

<template><div><div>我是子组件</div></div>
</template>

运行代码,发现,最终渲染的效果是

大家好我是父组件
我是子组件

那如果我想实现显示父组件中p标签的内容怎么办

修改子组件:myslot.vue

<template><div><div>我是子组件</div><p>现在测试一下slot</p><slot></slot></div>
</template>

运行代码,可以看到以下效果

大家好我是父组件
我是子组件
现在测试一下 slot
测试这里内容的能否显示

我们经常需要向一个组件传递内容

Vue 自定义的 元素让这变得非常简单

只要在需要的地方加入插槽就行了——就这么简单!

结合上面的例子来理解就是这样的:

1.父组件在引用子组件时希望向子组价传递模板内容 < p >测试一下吧内容写在这里了能否显示< /p >

2.子组件让父组件传过来的模板内容在所在的位置显示

3.子组件中的 < slot >就是一个槽,可以接收父组件传过来的模板内容,< slot > 元素自身将被替换

4.< myslot >< /myslot >组件没有包含一个 元素,则该组件起始标签和结束标签之间的任何内容都会被抛弃

二、插槽的作用

让用户可以拓展组件,去更好地复用组件和对其做定制化处理

三、插槽的分类

1.默认插槽

在一个< submit-button >组件中:

<button type = "submit">  <slot></slot>
</button>

我们可能希望这个 < button > 内绝大多数情况下都渲染文本“Submit”,但是有时候却希望渲染文本为别的东西,那怎么实现呢?

我们可以将“**Submit”**作为后备内容,我们可以将它放在 < slot > 标签内:

<button type = "submit" ><slot>Submit</slot>
</button>

现在当我在一个父级组件中使用 < submit-button > 并且不提供任何插槽内容时:

<submit-button></submit-button>

后备内容“Submit”将会被渲染:

<button type = "submit">Submit
</button>

但是如果我们提供内容:

<submit-button>Save
</submit-button>

则这个提供的内容将会被渲染从而取代后备内容:

<button type = "submit">Save
</button>

2.具名插槽

有时我们写了一个子组件,我们希望
<template><div class = "container"><header><!-- 我们希望把页头放这里 --></header><main><!-- 我们希望把主要内容放这里 --></main><footer><!-- 我们希望把页脚放这里 --></footer></div>
</template>

对于这样的情况, < slo t> 元素有一个特殊的 attribute: name。这个 attribute 可以用来定义额外的插槽:

<template><div class = "container"><header><slot name = "header"></slot></header>    <main><slot></slot></main><footer><slot name = "footer"></slot></footer></div>
</template>

一个不带 name 的 < slot > 出口会带有隐含的名字“default”。

父组件在向具名插槽提供内容的时候,我们可以在一个 < template > 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称:

     <template><myslot><div>大家好我是父组件</div><template v-slot:header><h1> Here might be a page title </h1></template><p>A paragraph for the main content </p><p>And another one </p>    <template v-slot:footer><p> Here's footer info </p></template></myslot></template>
<script>import myslot from './myslot';export default {components : {myslot}}
</script>

最终的渲染结果可以看到

Here might be a page title
大家好我是父组件
A paragraph for the main content
And another one
Here 's footer info

父组件中会向子组件中具名传递对应的模板内容,而没有指定名字的模板内容会传递给子组件中不带 name 的 < slot >

当然,如果父组件中

<template v-slot:default><p>A paragraph for the main content</p><p>And another one</p>
</template>

同样是传递给子组件中不带 name 的 < slot >

注意:

v-slot 只能添加在 < template > 上

具名插槽在书写的时候可以使用缩写, v-slot用#来代替

     <template><myslot><div>大家好我是父组件</div><template #header><h1>Here might be a page title</h1></template><p>A paragraph for the main content</p><p>And another one</p><template #footer><p>Here's footer info</p></template></myslot></template><script>import myslot from './myslot';export default {components: {myslot}}</script>

3.作用域插槽
这里主要解决的是父组件在向子组件插槽传递模板内容时存在访问子组件数据的问题

还记得默认插槽吗?如果子组件中写在 < slot > 标签内后备内容是与 该组件的data属性双向数据绑定的

       <template><div><span>      <slot>{{user.firstName}}</slot></span></div></template><script>export default {data () {return {user:{firstName:'gerace',lastName:'haLi'}}}}</script>

父组件在引用子组件时,希望能够换掉备用内容

         <template><myslot>{{ user.firstName }</myslot></template><script>import myslot from './myslot';export default {components: {myslot}}</script>

运行代码这时你会发现提示报错

Property or method “user” is not defined on the instance but referenced during render .

TypeError : Cannot read property ‘firstName’ of undefined

这里为什么?vue官方文档给出了答案

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的

那应该怎么解决这个问题?

为了让 user 在父级的插槽内容中可用,我们可以将 user 作为 < slot > 元素的一个 attribute 绑定上去:

       <span><slot v-bind:user="user">{{ user.lastName }}</slot></span>

绑定在 < slot > 元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot 来定义我们提供的插槽 prop 的名字:

        <template><myslot><template v-slot:default = "slotProps">{{ slotProps.user.firstName }}</template></myslot></template><script>import myslot from  './myslot';export default {components: {myslot}</script>

上面例子,我们选择将包含所有插槽 prop 的对象命名为 slotProps,但你也可以使用任意你喜欢的名字。

针对上面只给默认插槽传递模板内容的例子,在写法上可以采用默认插槽的缩写语法

      <template><myslot v-slot:default = "slotProps">{{ slotProps.user.firstName }}   </myslot>      </template><script>import myslot from './myslot';export default {components: {myslot}</script>

上面代码也可以直接改为

         <template><myslot v-slot="slotProps">{{ slotProps.user.firstName }}</myslot></template>

注意:
默认插槽的缩写语法不能和具名插槽混用,因为它会导致作用域不明确:

         <template><myslot v-slot="slotProps">{{ slotProps.user.firstName }}<template v-slot:other="otherSlotProps">slotProps is NOT available here</template></myslot></template>

下面再看一下多个插槽的情况

子组件

        <template><div><span><slot v-bind:userData="user" name = "header">{{ user.msg }}</slot><slot v-bind:hobbyData="hobby" name="footer">{{ hobby.fruit }}</slot></span></div></template><script>export default {data () {return {user:{firstName: 'gerace',lastName: 'haLi',},hobby:{fruit: "apple",color: "blue"}}}}</script>

父组件

          <template><myslot><template v-slot:header="slotProps">{{ slotProps.userData.firstName }}</template><template v-slot:footer = "slotProps">{{ slotProps.hobbyData.fruit}}</template></myslot></template><script>import myslot from './myslot';export default {components: {myslot}</script>

针对多个插槽的情况,在写法上可以解构插槽prop,父组件的写法如下

      <template><myslot><template v-slot:header="{userData}">{{ userData.firstName }}</template><template v-slot:footer="{hobbyData}">{{ hobbyData.fruit }}</template></myslot></template><script>import  myslot from  './myslot';export default {components: {myslot}}
</script>

在具名插槽的介绍部分有讲过,具名插槽可以使用缩写, v-slot可以使用#来代替,所以以上代码可以写成:

        <template><myslot><template #header="{userData}">{{ userData.firstName }}</template><template #footer="{hobbyData}">{{ hobbyData.fruit }}</template></myslot></template><script>import myslot from './myslot';export default {components: {myslot}}</script>

但是需要注意的是该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:

<!-- 这样会触发警告 --><template><myslot><template #="{userData}">{{ userData.firstName }}</template><template #="{hobbyData}">{{ hobbyData.fruit }}</template></myslot></template>

细讲Vue中的插槽slot相关推荐

  1. vue中的插槽--slot和v-slot

    今天团队内部有一个技术分享会,主要是vue进阶这一块,我对插槽slot的认识还不清晰,于是就总结一下 什么是插槽? 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容, ...

  2. 理解vue中的插槽------slot与slot-scope-已整理

    vue当中的插槽,指的即是slot,是组件当中的一块HTML模板.该模板是否显示,以及如何显示由其父组件说了算.不过插槽显示的位置是由子组件决定 ,你将slot写在组件template的哪块,父组件传 ...

  3. vue 中的插槽Slot基本使用和具名插槽

    一.插槽Slot的作用 1.为了让这个组件具备更强的通用性,我们不能将组件中的内容限制为固定的div.span等等这些元素: 2.比如某些情况下我们使用组件,希望组件显示的是一个按钮,某种情况下我们使 ...

  4. vue中的插槽(slot)

    vue中有3种插槽 1.默认插槽 <slot></slot> 2.具名插槽 <slot name="名称"></slot> 3.作用 ...

  5. Vue在渲染函数createELement和JSX中使用插槽slot

    Vue对于插槽有两个专门的APIvm.$slots和vm.$scopedSlots,分别是普通插槽和作用域插槽,使用JSX语法或渲染函数的时候,定义插槽将使用上述两个API. 渲染函数createEl ...

  6. Vue中的Ajax②(slot插槽)

    文章目录 案例引入 默认插槽 具名插槽 作用域插槽 总结 案例引入 我们现在有一个需求: 代码: App组件: <template><div class="containe ...

  7. vue中v-solt插槽的使用

    具名插槽slot与v-solt插槽 使用插槽分成两步. 第一步 在组件元素内.为其它元素设置插槽名称. 通过slot属性设置. 第二步 在组件模板中,通过slot组件,使用这些元素. 通过name属性 ...

  8. Vue学习Day6 插槽slot使用、编译作用域、作用域插槽、模块化开发、webpack介绍、安装

    想利用暑假时间好好学习一下vue,会记录每一天的学习内容. 今天是学习vue的第6天! 起起伏伏乃人生常态,继续加油- 学习内容 1. 插槽slot slot基本使用 具名插槽slot 2. 编译作用 ...

  9. slot传函数 vue_vue中的插槽slot理解

    本篇文章参考赛冷思的个人博客 1.函数默认传参 在我们写js函数我们的可能会给他们一个默认的参数,写法是 functionshow(age,name){var age = age || 20;var ...

最新文章

  1. qq动态页面变方格_微信更新“分组显示、群管理”等功能,网友:都是QQ玩剩的姿势...
  2. iphone内关于sqlite开发的相关教程
  3. 小小总结一下目前的财政
  4. py获取前端的参数_Python小工具系列(3)之参数检查
  5. 虚拟化四路服务器,IDC:4路及8路服务器现状未来趋势分析
  6. 使用xml和java代码混合控制UI界面
  7. 【2016Esri全球用户大会主题亮点】GIS is Getting Smarter——JACK主题演讲权威解读
  8. LaTex的图文安装--TexLife+SumtraPDF+Vscode
  9. 轻松学,听说你还没有搞懂 Dagger2
  10. ESP32编程使用OLED屏
  11. 性能测试能力提升最终篇-全链路压测
  12. python map函数的作用_python语言基础之map函数,urlib.request,多线程
  13. 基于Node.js的图书管理系统
  14. 基于区块链技术的冷链食品疫情防控管理系统的实现
  15. 随机漫步模拟及概率分析
  16. CancerSubtypes包的介绍(根据生信技能树Jimmy老师分享的乳腺癌分子分型包资料整理)
  17. 电脑摄像头无法打开,没有图像的解决办法之一
  18. 微信好友数据统计,能测出删除你的好友
  19. 【作业】WLAN无线
  20. python3[爬虫实战] 使用selenium,xpath爬取京东手机(下)

热门文章

  1. windows下如何用python控制打印机打印_在windows上使用python设置打印机权限
  2. Python基础:标准库和常用的第三方库
  3. 【编译原理】期末 龙书概念梳理+做题方法(混子保过指南+学霸提分秘籍)
  4. Java如何获取系统时间
  5. 深入理解微信小程序的底层框架(一)
  6. 手机怎样显示0的电量?
  7. 华硕x580nv拆机_做工扎实用料足 华硕S56超极本拆解图
  8. 【仙女踩坑实录】解决18MacbookPro外接显示器后发热严重
  9. Http请求头 缓存
  10. unity3d实现第一人称射击游戏之CS反恐精英(三)(人物旋转限制和跳跃功能(消除连跳,碰撞消除,高度稳定))