vue组件间传值之插槽

什么是插槽?

插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制。

vue中插槽也是父子组件通讯的一种方式。

组件最大的特性就是复用性,插槽能大大提高组件的复用性。

  1. 通过插槽 ,父组件可以把一段(模板的)结构传递给子组件 。
  2. 用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容
  3. vue提供组件插槽能力, 允许开发者在封装组件时,把不确定的部分定义为插槽

组件插槽的基本使用

        <div id="app">
			<my-com>Hello </my-com>
			<my-com>
				<a href="">点击</a>
			</my-com>
			<my-button>点击</my-button>
			<my-button>提交</my-button>
			<my-button @click="num++">
				<div>总共点击了{
   
   {num}}次</div>
			</my-button>
		</div>
		<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.js"></script>
		<script>
			var app=Vue.createApp({
				data:function(){
					return{
						num:0
					}
				},
				methods: {
				},
			});
			app.component("MyCom",{
				template:`<div class="my-com">
					子组件
					<div>
					<slot></slot>
					</div>
				</div>`,
			});
			app.component("MyButton",{
				template:`<button>
					<slot></slot>
				</button>`,
			});
			app.mount("#app");
		</script>

具名插槽

  • 具有名字的插槽
  • 使用 中的 “name” 属性绑定元素
  • 通过slot属性来指定, 这个slot的值必须和下面slot组件得name值对应上 如果没有匹配到 则放到匿名的插槽中
        <div id="app">
			<my-com>
				<!-- 具名插槽 -->
				<template v-slot:header>头部</template>
				<template v-slot:default> 默认插槽</template>
				<!-- <template v-slot:footer>底部</template> -->
				<!-- 简写 v-slot用#代替-->
				<template #footer>底部</template>
			</my-com>
		</div>
		<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.js"></script>
		<script>
			var app=Vue.createApp({
				data:function(){
					return{
						num:0
					}
				},
				methods: {
				},
			});
			app.component("MyCom",{
				template:`<div class="my-com">
					<div class="header">
						<slot name="header"></slot>
					</div>
					<div class="body">
						<slot></slot>
					</div>
					<div class="footer">
						<slot name="footer"></slot>
					</div>
				</div>`,
			});
			app.mount("#app");
		</script>

总之,slot存在于子组件,v-slot在父组件,最终页面展示结果是父组件!!!

作用域插槽:父组件对子组件的内容进行加工处理。

作用域插槽也可以理解为带数据的插槽,即带参数的插槽,简单的来说就是子组件提供给父组件的参数,该参数仅限于插槽中使用,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。

        <div id="app">
			<my-com>
				<!--子给父传:父组件接受子组件传过来的值 -->
				<template v-slot:header="data">
					<!-- data只能在当前模板内部使用 -->
					头部
					{
   
   {data}}
					<br>
					{
   
   {data.msg}}
				</template>
				<!--解构赋值: v-slot:default="msg,age" -->
				<template v-slot:default="{msg:text,age}"> 
					默认插槽
					<!--msg 别名text -->
					{
   
   {text}}
					{
   
   {age}}
				</template>
				<template #footer>底部</template>
			</my-com>
		</div>
		<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.js"></script>
		<script>
			var app=Vue.createApp({
				data:function(){
					return{
						num:0
					}
				},
				methods: {
				},
			});
			app.component("MyCom",{
				template:`<div class="my-com">
					<div class="header">
						<slot name="header" :msg="msg" :age="age"></slot>
					</div>
					<div class="body">
						<slot :msg="msg" :age="age"></slot>
					</div>
					<div class="footer">
						<slot name="footer"></slot>
					</div>
				</div>`,
				data(){
					return{
						msg:"Jack",
						age:10,
					}
				}
			});
			
			app.mount("#app");
		</script>

结果:

父组件给子组件数据,在父组件可以通过:data的形式实现:

        <div id="app">
			<my-com>
				<template v-slot:header :data="datas">
					<!-- data只能在当前模板内部使用 -->
					头部
					{
   
   {datas}}
					<br>
					{
   
   {datas.msg}}
				</template>	
			</my-com>
		</div>

补充:作用域插槽与element-plus的联合使用

        <div id="app">
			<el-table :data="tableData" style="width: 100%">
				<el-table-column label="日期" prop="date" width="180">
				</el-table-column>
				<el-table-column label="名字" prop="name" width="180">
					<template #default="{row}"><span>{
   
   {row.name}}</span></template>
				</el-table-column>
				<el-table-column label="地址" prop="address" width="180">
				</el-table-column>
				<el-table-column label="Operations">
					<template #default="{row}">
						<el-button @click="onClick(row)" type="success">详情</el-button>
					</template>
				</el-table-column>
			  </el-table>
		</div>
		<script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.37/vue.global.js"></script>
		<script src="https://cdn.bootcdn.net/ajax/libs/element-plus/2.2.10/index.full.min.js"></script>
		<script>
			var app=Vue.createApp({
				data:function(){
					return{
						num:0,
						tableData:[
						  {
						    date: '2016-05-03',
						    name: 'Tom',
						    address: 'No. 189, Grove St, Los Angeles',
						  },
						  {
						    date: '2018-05-20',
						    name: 'Jack',
						    address: 'No. 189, Grove St, Los Angeles',
						  },
						  {
						    date: '2020-05-04',
						    name: 'Rose',
						    address: 'No. 189, Grove St, Los Angeles',
						  },
						  {
						    date: '2022-11-29',
						    name: 'Lucy',
						    address: 'No. 189, Grove St, Los Angeles',
						  },
						]
					}
				},
				methods: {
					onClick(row){
						console.log(row);
					}
				},
			});
			app.use(ElementPlus);//注册组件
			app.mount("#app");
		</script>

猜你喜欢

转载自blog.csdn.net/Doulvme/article/details/126284415