欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 艺术 > Vue 系列之:插槽

Vue 系列之:插槽

2025/3/9 6:11:51 来源:https://blog.csdn.net/weixin_48241989/article/details/146098715  浏览:    关键词:Vue 系列之:插槽

前言

插槽是定义在子组件中的,相当于一个占位符,父组件可以在这个占位符中填充HTML代码、组件等内容。

插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制。

基本使用

子组件:

<template><div><h1>今天天气状况:</h1><slot></slot></div>
</template><script>
export default {name: 'child'
}
</script>

父组件:

<template><div class="box"><div>使用slot分发内容</div><child><div>多云</div></child></div>
</template><script>
import Child from './Child.vue';
export default {components: { Child },
};
</script><style scoped>
.box {margin: 20px;
}
</style>

在这里插入图片描述

如果把子组件中 slot 去掉,父组件不变:

<template><div><h1>今天天气状况:</h1><!-- <slot></slot> --></div>
</template><script>
export default {name: 'child'
}
</script>

在这里插入图片描述

如果子组件没有使用插槽,父组件如果需要往子组件中填内容是没法做到的。

具名插槽

具名插槽其实就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。

子组件

<template><div><div class="top"><h1>头部</h1><slot name="top"></slot> <!--具名插槽1--></div><div class="center"><h1>中间</h1><slot></slot> <!--默认插槽--></div><div class="bottom"><h1>底部</h1><slot name="bottom"></slot> <!--具名插槽2--></div></div>
</template><script>
export default {name: "child",
};
</script><style scoped>
.top {background-color: aqua;
}
.center {background-color: pink;
}
.bottom {background-color: aquamarine;
}
</style>

父组件:

<template><div class="box"><div>使用slot分发内容</div><child><!--所有没指定插槽名称的会添加到默认插槽中--><div>A</div><div>B<span>C</span></div><!--具名插槽写法1--><div slot="bottom">E</div><!--具名插槽写法2--><template v-slot:top><div>D</div></template></child></div>
</template><script>
import Child from "./Child.vue";
export default {components: { Child },
};
</script><style scoped>
.box {margin: 20px;
}
</style>

在这里插入图片描述

无论父组件中插槽的顺序是怎样的,最终渲染结果都以子组件中插槽的顺序为准。

作用域插槽

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

子组件:

<template><div><h1>我是子组件</h1><slot :aa="list" bb="123"></slot></div>
</template><script>
export default {name: "child",data() {return {list: [1,2,3,4,5]}}
};
</script>

父组件:

<template><div class="box"><div>我是父组件</div><child><div slot-scope="ss1"><!--ss1这个名字是随便取的-->{{ ss1 }}<div>呵呵</div></div></child><hr /><child><div slot-scope="{ bb }"> <!--括号中的属性名必须是子组件中存在的-->{{ bb }}<div>嘻嘻</div></div></child><hr /><child><ul slot-scope="ss2"><li v-for="(item, index) in ss2.aa" :key="index">{{ item }}</li></ul></child><hr /><child> 哈哈 </child></div>
</template><script>
import Child from "./Child.vue";
export default {components: { Child },
};
</script><style scoped>
.box {margin: 20px;
}
</style>

在这里插入图片描述

使用场景:如果子组件中的某一部分的数据,每个父组件都会有自己的一套对该数据的不同的呈现方式,这时就需要用到作用域插槽。

Vue2 和 Vue3 写法的区别

主要是一些写法上的区别

具名插槽

Vue2:

<!--子组件-->
<slot name="top"></slot><!--父组件-->
<div slot="top">xxx</div>

Vue3:

<!--子组件-->
<slot></slot>
<slot name="top"></slot><!--父组件-->
<template v-slot><div>xxx</div>
</template><template #default><div>xxx</div>
</template><template v-slot:top><div>xxx</div>
</template><template #top><div>xxx</div>
</template>

作用域插槽

Vue2:

<!--子组件-->
<slot :aa="list" bb="123"></slot>
// list: [ 1, 2, 3, 4, 5 ]<!--父组件-->
<div slot-scope="ss1">{{ ss1 }} //输出 { "aa": [ 1, 2, 3, 4, 5 ], "bb": "123" }
</div><div slot-scope="{ bb }"> <!--括号中的属性名必须是子组件中存在的-->{{ bb }}  // 输出 123
</div>

Vue3:

<!--子组件-->
<slot :aa="list" bb="123" name="top"></slot><!--父组件-->
<template v-slot:top="ss1"><div>{{ ss1 }}</div> //输出 { "aa": [ 1, 2, 3, 4, 5 ], "bb": "123" }
</template><template v-slot:top="{ bb }"><div>{{ bb }}</div> // 输出 123
</template>

Vue3 写法扩展

<!--子组件-->
<template><div><h1>我是子组件</h1><slot :aa="list" bb="123"></slot><slot name="top"></slot></div>
</template><script>
export default {name: "child",data() {return {list: [1,2,3,4,5]}}
};
</script><style scoped>
</style>
<!--父组件-->
<template><div class="box"><div>我是父组件</div><child><template v-slot="ss1"><div>传递所有参数:{{ ss1 }}</div></template></child><child><template v-slot="{ bb }"><div>通过解构传递具体参数:{{ bb }}</div></template></child><child><template v-slot="{ bb: haha }"><div>参数重命名:{{ haha }}</div></template></child><child><template v-slot="{ cc = '默认值' }"><div>参数默认值:{{ cc }}</div></template></child><child><template v-slot:[slotName]="{ dd = '默认值' }"><div>动态插槽名和默认值:{{ dd }}</div></template></child></div>
</template><script>
import Child from "./Child.vue";
export default {components: { Child },data() {return {slotName: "top",};},
};
</script><style scoped>
.box {margin: 20px;
}
</style>

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词