为什么使用slot
slot翻译为插槽: 在生活中很多地方都有插槽,电脑的USB插槽,插板当中的电源插槽插槽的目的是让我们原来的设备具备更多的扩展性比如电脑的USB我们可以插入U盘、硬盘、手机、音响、键盘、鼠标等等 组件的插槽: 组件的插槽也是为了让我们封装的组件更加具有扩展性让使用者可以决定组件内部的一些内容到底展示什么 举例:移动网站中的导航栏 移动开发中,几乎每个页面都有导航栏。导航栏我们必然会封装成一个插件,比如nav-bar组件。一旦有了这个组件,我们就可以在多个页面中复用了如何去封装这类的组件呢? 它们也很多区别,但是也有很多共性如果我们每一个单独去封装一个组件,显然不合适:比如每个页面都有返回,这部分内容我们就要重复去封装但是,如果我们封装成一个,好像也不合理:有些左侧是菜单,有些是返回,有些中间是搜索,有些是文字等等 如何封装合适呢?抽取共性,保留不同 最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽一旦我们预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容是搜索框,还是文字,还是菜单。由调用者自己来决定。
子组件中引入插槽(以插入button为例):
子组件(HelloWorld.vue):
<template><div class="hello">hello<slot></slot></div></template>
父子组件引入button:
<template><div class="hello"><HelloWorld><button>click</button><!-- 插槽中插入一个button --></HelloWorld> </div></template>
插槽的基本使用:<slot></slot>
插槽可以添加默认值:<slot><button>默认按钮</button></slot>
,若插入其他元素可以替换掉默认值如果有多个值,同时放入到组件中进行替换时,一起作为替换元素
具名插槽slot
当子组件的功能复杂时,子组件的插槽可能并非是一个 比如我们封装一个导航栏的子组件,可能就需要三个插槽,分别代表左边、中间、右边那么,外面在给插槽插入内容时,如何区分插入的是哪一个呢?这个时候,我们就需要给插槽起一个名字 如何使用具名插槽呢? 非常简单,只要给slot元素一个name属性即可<slot name="center"></slot>
子组件(默认三个插槽):
<template><div class="hello"><slot name="left"><span>左边</span></slot><slot name="center"><span>中间</span></slot><slot name="right"><span>右边</span></slot></div></template>
父组件(替换掉中间中的内容为标题):
<template><div class="hello"><HelloWorld><span slot="center">标题</span></HelloWorld></div></template>
作用域插槽
父组件替换插槽的标签,但是内容由子组件来提供我们先提一个需求: 子组件中包括一组数据,比如:planguages:[ ‘Javascript’, ‘Python’, ‘Swift’, ‘Go’, ‘C++’]需要在多个界面进行展示: 某些界面是以水平方向展示的某些界面是以列表形式展示的某些界面直接展示一个数组 内容在子组件,希望父组件告诉我们如何展示,怎么办呢? 利用slot作用域插槽就可以了子组件(默认以list形式展示)
<template><div class="hello"><slot :data_1="planguages"> <!-- 子组件插槽绑定子组件中的数据 --><ul><li v-for="(item,index) in planguages" :key="index">{{ item }}</li></ul></slot></div></template><script>export default {name: "HelloWorld",data() {return {planguages:['Javascript', 'Python', 'Swift', 'Go', 'C++']};}};</script>
父组件以多种方式展示子组件中数据:
<template><div class="hello"><HelloWorld></HelloWorld><!-- 列表 --><HelloWorld><template slot-scope="slot_1"><span>{{ slot_1.data_1.join(' - ') }}</span> <!-- 水平展示 --></template></HelloWorld><HelloWorld><template slot-scope="slot_2"><span>{{ slot_2.data_1 }}</span> <!-- 数组展示 --></template></HelloWorld></div></template>