作用:
通过使用插槽让组件更加灵活和具有可复用性,使其用在不同的地方渲染不同的内容,同时保证相同的样式。
插槽作用域:由于插槽内容本身就是在父组件中定义的,所以可以访问到父组件的数据作用域,但是无法访问到自组件的数据作用域。因为vue表达式和js的词法作用域规则一样,只能访问其定义时所处的作用域。用官方文档来说就是:
父组件模版中的表达式只能访问父组件的作用域;子组件模版中的表达式只能访问子组件的作用域。
插槽的使用:
(1)默认插槽:又称匿名插槽。
即外部没有提供任何内容时,为插槽提供默认内容。
<button type="submit">
<slot></slot>
</button>
(2)具名插槽:
在一个组件中包含多个插槽出口时,使用具名插槽。<slot>元素通过唯一特殊的name,来给各插槽分配唯一的ID,来确定每一处需要渲染的内容。
没有提供name的<slot>出口则会隐式的命名为"default"(匿名插槽)。
父组件使用 <template v-slot:charts> 代码将这部分内容模版片段传入到自组件的charts插槽中:
所以可以尝试:
子组件样式和内容:
<div class="slot-container">
<slot name="charts"></slot>
<slot name="tables"></slot>
</div>
引入父组件:
<SlotContainer>
<template v-slot:charts>
<p>this is 父组件</p>
</template>
</SlotContainer>
v-slot对应简写 # ,因此 <template v-slot:charts> 可以简写为 <template #charts>。
展示效果:
(3)动态插槽名:
即动态参数在v-slot上也是有效的,由此可以定义:
自组件内容不变,父组件内容:
<SlotContainer>
<template #[dynamicName]>
<p>this is 父组件{{dynamicName}}</p>
</template>
</SlotContainer>
定义dynamicName:
const dynamicName = ref('charts')
效果展示:
(4)作用域插槽:
插槽的内容时父组件的数据作用域,无法访问到子组件的状态,但是使用作用域插槽来同时使用父组件域内和子组件域内的数据。由此可以像组件传递props那样,向一个插槽的出口上传递attributes:
然后由父组件接受插槽的props。
默认插槽直接使用 <SlotContainer v-slot="slotProps"> 进行接收;
具名插槽则:
子组件内容:
<slot name="charts" :data="formList"></slot>
const formList = ref('this is 子组件')
父组件接收:
<SlotContainer>
<template v-slot:[dynamicName]="chartsProps">
<p>this is 父组件</p>
<p>{{chartsProps.data}}</p>
</template>
</SlotContainer>
效果展示:
即将子组件的 formData 传入到父组件中。