ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] >[success] # 使用匿名插槽和具名插槽解决组件内容传递问题 ![](https://img.kancloud.cn/44/95/44959a263d09c0f9581168b801e0b85d_355x43.png) 需求:如图,封装了一个 **表单组件** ,但是 **按钮不想固定,假如说按钮的位置:我想展示一个div就展示div,想展示button就展示button** ,用 **slot插槽** 就能解决我们的问题。 >[success] ## 匿名插槽 **匿名插槽** : **就是没有名称的插槽随插随用** ,缺点,只有 **使用一个插槽时候可以使用,同时使用多个插槽时候,就不知道插入到哪里了** 。 **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用插槽和具名插槽解决组件内容传递问题</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // slot 插槽 // slot 中使用的数据,作用域的问题 // 父模板里调用的数据属性,使用的都是父模板里的数据 // 子模板里调用的数据属性,使用的都是子模板里的数据 // 父组件 const app = Vue.createApp({ data(){ return { text: '提交' } }, template: ` <myform> <div>{{text}}</div> </myform> <myform> <button>{{text}}</button> </myform> <myform></myform> ` }) // 子组件 app.component('myform', { methods: { handleClick(){ alert(123) } }, template: ` <div> <input /> <span @click="handleClick"> <slot>默认值占位符</slot> </span> </div> ` }) const vm = app.mount('#root') </script> </html> ~~~ >[success] ## 具名插槽 **具名插槽**: **明确指定 name ,给对应 name 的 slot 标签中添加对应的内容** 。 **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用插槽和具名插槽解决组件内容传递问题</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // slot 插槽 // slot 中使用的数据,作用域的问题 // 父模板里调用的数据属性,使用的都是父模板里的数据 // 子模板里调用的数据属性,使用的都是子模板里的数据 // 具名插槽 // 父组件 const app = Vue.createApp({ template: ` <layout> <template v-slot:header> <div>header</div> </template> <template v-slot:footer> <div>footer</div> </template> </layout> ` }) // 子组件 app.component('layout', { template: ` <div> <slot name="header"></slot> <div>content</div> <slot name="footer"></slot> </div> ` }) const vm = app.mount('#root') </script> </html> ~~~ 使用 **具名插槽** 时 , **父组件** 中要用 **template标签包裹** ,然后写上 **v-slot:插槽名称** ,在 **template标签包裹** 中写要 **插入的内容** 。 >[success] ### 具名插槽语法简写 可以把 **template标签** 上的 **v-slot:header** ,简写成 **#header** 。 **index.html** ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>使用插槽和具名插槽解决组件内容传递问题</title> <!-- 通过cdn方式引入vue --> <script src="https://unpkg.com/vue@next"></script> </head> <body> <div id="root"></div> </body> <script> // slot 插槽 // slot 中使用的数据,作用域的问题 // 父模板里调用的数据属性,使用的都是父模板里的数据 // 子模板里调用的数据属性,使用的都是子模板里的数据 // 具名插槽 // 父组件 const app = Vue.createApp({ template: ` <layout> <template #header> <div>header</div> </template> <template #footer> <div>footer</div> </template> </layout> ` }) // 子组件 app.component('layout', { template: ` <div> <slot name="header"></slot> <div>content</div> <slot name="footer"></slot> </div> ` }) const vm = app.mount('#root') </script> </html> ~~~ >[warning] ## 注意 1. 使用 **slot插槽** 时,必须要用 **双标签包裹** 2. **slot标签** 是没有办法直接 **绑定事件** 的