VUE系列文章-插槽

213 阅读2分钟

默认插槽

//父组件
<template>
  <div>
  	<h3>父组件</h3>
  	<child>
  		<p>传递的内容</p>
  	</child>
  </div>
</template>

//子组件
<template>
	<div>
  	<h3>子组件</h3>
  	<slot></slot>
  </div>  
</template>

渲染结果

<div>
	<h3>父组件</h3>
  <div>
    <h3>子组件</h3>
    <p>传递的内容</p>
  </div>
</div>

具名插槽

//父组件
<template>
  <div>
  	<h3>父组件</h3>
  	<child>
      <template v-slot:msg>
        <p>传递的内容1</p>
			</template>
			<template v-slot:tool>
        <p>传递的内容2</p>
			</template>
  	</child>
  </div>
</template>

//子组件
<template>
	<div>
  	<h3>子组件</h3>
  	<slot name="msg"></slot>
    <slot name="tool"></slot>
  </div>  
</template>

插槽中传值

//父组件
<todo-list>
  <template v-slot:todo="{ todo }">
    <span v-if="todo.isComplete">✓</span>
    {{ todo.text }}
  </template>
</todo-list>

//子组件 TodoList.vue
<ul>
  <li>
    //通过v-bind给slot传值
    <slot name="todo" v-bind:todo="todo">
      <!-- 后备内容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

具名插槽的简写(#简写只适应具名插槽 作用于插槽 动态插槽无效)

//父组件
<template>
  <div>
  	<h3>父组件</h3>
  	<child>
      <template #msg>
        <p>传递的内容1</p>
			</template>
			<template #tool>
        <p>传递的内容2</p>
			</template>
  	</child>
  </div>
</template>

//子组件
<template>
	<div>
  	<h3>子组件</h3>
  	<slot name="msg"></slot>
    <slot name="tool"></slot>
  </div>  
</template>

作用域插槽

//父组件
<template>
  <div>
  	<h3>父组件</h3>
  	<child>
      <template v-slot:msg="slotProps">
        <p>{{slotProps.info}}</p> //这是获取的子组件的内容
			</template>
			//解构的用法
			<template v-slot:msg="{info}">
        <p>{{info}}</p> //这是获取的子组件的内容
			</template>
  	</child>
  </div>
</template>

//子组件
<template>
	<div>
  	<h3>子组件</h3>
  	<slot name="msg" :info="info"></slot>
  </div>  
</template>
<script>
	export default {
    data(){
      return{
        info:'这是获取的子组件的内容'
      }
    }
  }
</script>

动态插槽名

//子组件 TodoList.vue
<template>
    <div class="todolist">
        <slot name="header">1</slot>
        <slot name="content">2</slot>
        <slot name="footer">3</slot>
    </div>
</template>
//父组件
<TodoList>
  <template #header>
		这是头部
  </template>
  <template v-slot:[dynamicSlotName]>
		这是动态的部分
  </template>
</TodoList>
<script>
import TodoList from './TodoList.vue';
export default {
  data() {
    return {
      dynamicSlotName: 'footer',
    };
  },
  components: {
    TodoList,
  },
};
</script>