Vue入门【六】-- 普通插槽与作用域插槽

发布于:2022-12-06 ⋅ 阅读:(201) ⋅ 点赞:(0)

普通插槽

在开发中,我们会经常封装一个个可复用的组件,前面我们会通过props传递给组件一些数据,让组件来进行展示,但是为了让这个组件具备更强的通用性,我们不能将组件中的内容限制为固定的div、span等等这些元素,比如某种情况下我们希望组件显示的是一个按钮又或者某种情况下我们使用组件希望显示的是一张图片,因此我们应该让使用者去决定某一块区域到底存放什么内容。

普通插槽分为默认插槽和具名插槽:

其中没有名字的插槽就是默认插槽,具名插槽就是有名字的插槽。

普通插槽的基本使用

(1)定义一个有插槽的组件myA

 没有写名字的就是默认插槽,又名瞎子的就是具名插槽

        // 定义组件 
		let myA={
			template:`
				<div>
					子组件A
					<slot></slot>
					<slot name='header'></slot>	
					<slot name='center'></slot>	
					<slot name='footer'></slot>
				</div>
			
			`,

 (2)在全局注册这个组件

components:{
				'my-a':myA
			},

(3)在插槽中放入需要显示的内容

注意:没有名字的内容会被填充到没有名字的插槽;

           有名字的插槽使用v-slot与指定插槽进行绑定。

           v-slot可以简写为 #

	<div id="app">
		<my-a>

			<!-- 没有名字的内容会被填充到没有名字的插槽 -->
			<!-- 默认内容---默认插槽 -->
			<div>父组件传递给子组件的模块</div>
			
			<!-- 具名插槽:有名字的插槽 -->
			<!-- 将template填充到名为center的插槽中 -->
			<!-- 插槽允许我们在调用子组件时提供给子组件一个模板 -->
			<!-- 使用v-slot与指定插槽进行绑定 -->
			<!-- v-slot可以简写为 # -->
			<template class="header" #header>脑袋里有什么</template>
			<template class="center" v-slot:center>肚子里有什么</template>
			<template class="footer" v-slot:footer>踩到柠檬片了</template>
		</my-a>
	</div>

 渲染至页面的效果:

 

注意:有时候我们希望在使用插槽时,如果没有插入对应的内容,那么我们需要显示一个默认的内容,当然这个默认的内容只会在没有提供插入的内容时,才会显示。

<template>
  <div>
    <slot>
      <i>我是默认的i元素</i>
    </slot>
  </div>
</template>

作用域插槽

概念:由于父级模板里的所有内容都是在父级作用域中编译的,子模板里的所有内容都是在子级作用域中进行编译的,因此父组件无法访问到子组件的数据的,但是有时候我们确实希望父组件在使用插槽的同时也可以访问到子组件中的内容,因此vue便给我们提供了作用域插槽。

关于使用场景,可以参考这篇博客:vue作用域插槽,你真的懂了吗?_普通网友的博客-CSDN博客 

作用域插槽的基本使用

父组件中:

在父组件中使用子组件

<div id="app">
        <my-a :arr="arr">
             // zzy 是自由命名的
			<template slot-scope="zzy">
				{{zzy.a}}
			</template>		
		</my-a>
    </div>
		new Vue({
            components:{
				'my-a':myA
			},
			el:"#app",
			data:{
				arr:[
					{
						id:1,
						title:'xxxxxxx'
					},
					{
						id:2,
						title:'yyyyyy'
					},
					{
						id:3,
						title:'zzzzzz'
					}
				]
			},
			methods:{}
		})

子组件中:

将子组件定义为一个插槽并在其中定义一个props去接收父组件传递出来的值

        // 定义组件
		let myA={
			props:['arr'],
			template:`
				<div>
					子组件A
					<ul>
						<li v-for='item in arr'>{{item.title}}
                            // a也是自由命名的
							<slot v-bind:a=item></slot>	
						</li>	
					</ul>					
				</div>
			`,
			
		}

效果:

思路:先将数据通过父传子的形式传递给子组件,子组件定义为插槽的形式去在父组件中使用,那么此时便可以在父组件中使用子组件中的数据了。