Slots for passing values between vue components

What are slots?

A slot is a placeholder in a child component that is provided to the parent component. It means that the parent component can fill any template code in this placeholder, such as HTML, components, etc., and the filled content will replace the label of the child component . Whether the slot is displayed or not and how to display it is controlled by the parent component, while where the slot is displayed is controlled by the child component.

Slots in Vue are also a way for parent-child components to communicate.

The biggest feature of components is reusability, and slots can greatly improve the reusability of components.

  1. Through slots, parent components can pass a piece of (template) structure to child components.
  2. It is used to realize the content distribution of the component. Through the slot label, the content written in the component label can be received
  3. Vue provides component slot capability, allowing developers to define uncertain parts as slots when packaging components

Basic use of component slots

        <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>

named slot

  • a slot with a name
  • Use the "name" attribute in the bound element
  • It is specified by the slot attribute. The value of this slot must correspond to the name value of the slot component below. If there is no match, it will be placed in an anonymous slot.
        <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>

In short, the slot exists in the child component, the v-slot is in the parent component, and the final page display result is the parent component! ! !

Scope slot: The parent component processes the content of the child component.

Scope slots can also be understood as slots with data, that is, slots with parameters. Simply put, they are the parameters provided by the child component to the parent component. This parameter is only used in the slot, and the parent component can be used according to the child component The passed slot data is used to display and fill the slot content in different ways.

        <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>

result:

The parent component gives data to the child component, which can be realized in the form of: data in the parent component:

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

Supplement: Combined use of scoped slots and 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>

 

Guess you like

Origin blog.csdn.net/Doulvme/article/details/126284415