文章目录
前言
在组件编译过程中,有时候不能确定组件内不确定具体要写什么,这时候就需要插槽,插槽是什么?在官方文档中是这样定义的
插槽(slot)是 vue 为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。
其实插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。
作用
让父组件可以向子组件指定位置插入html结构,也是一种组件间通信的方式,适用于 父组件 ===> 子组件
分类
插槽可分为默认插槽,具名插槽,作用域插槽
默认插槽
模板
父组件中: <Category> <div>html结构1</div> </Category> 子组件中: <template> <div> <!-- 定义插槽 --> <slot>插槽默认内容...</slot> </div> </template>
使用方式
app.vue: <template> <div class="container"> <Category title="美食" > <img src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt=""> </Category> <Category title="游戏" > <ul> <li v-for="(g,index) in games" :key="index">{{g}}</li> </ul> </Category> <Category title="电影"> <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video> </Category> </div> </template> <script> import Category from './components/Category' export default { name:'App', components:{Category}, data() { return { foods:['火锅','烧烤','小龙虾','牛排'], games:['红色警戒','穿越火线','劲舞团','超级玛丽'], films:['《教父》','《拆弹专家》','《你好,李焕英》','《尚硅谷》'] } }, } </script> 子组件: <template> <div class="category"> <h3>{{title}}分类</h3> <!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) --> <slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot> </div> </template> <script> export default { name:'Category', props:['title'] } </script>
具名插槽
模板
父组件中: <Category> <template slot="center"> <div>html结构1</div> </template> <template v-slot:footer> <div>html结构2</div> </template> </Category> 子组件中: <template> <div> <!-- 定义插槽 --> <slot name="center">插槽默认内容...</slot> <slot name="footer">插槽默认内容...</slot> </div> </template>
使用方式
app.vue <template> <div class="container"> <Category title="美食" > <img slot="center" src="https://s3.ax1x.com/2021/01/16/srJlq0.jpg" alt=""> <a slot="footer" href="#">更多美食</a> </Category> <Category title="游戏" > <ul slot="center"> <li v-for="(g,index) in games" :key="index">{{g}}</li> </ul> <div class="foot" slot="footer"> <a href="">单机游戏</a> <a href="">网络游戏</a> </div> </Category> <Category title="电影"> <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"></video> <template v-slot:footer> <div class="foot"> <a href="">经典</a> <a href="">热门</a> <a href="">推荐</a> </div> <h4>欢迎前来观影</h4> </template> </Category> </div> </template> 子组件: <template> <div class="category"> <h3>{{title}}分类</h3> <!-- 定义一个插槽(挖个坑,等着组件的使用者进行填充) --> <slot name="center">我是一些默认值,当使用者没有传递具体结构时,我会出现1</slot> <slot name="footer">我是一些默认值,当使用者没有传递具体结构时,我会出现2</slot> </div> </template> <script> export default { name:'Category', props:['title'] } </script>
作用域插槽
模板
父组件中: <Category> <template scope="scopeData"> <!-- 生成的是ul列表 --> <ul> <li v-for="g in scopeData.games" :key="g">{{g}}</li> </ul> </template> </Category> <Category> <template slot-scope="scopeData"> <!-- 生成的是h4标题 --> <h4 v-for="g in scopeData.games" :key="g">{{g}}</h4> </template> </Category> 子组件中: <template> <div> <slot :games="games"></slot> </div> </template> <script> export default { name:'Category', props:['title'], //数据在子组件自身 data() { return { games:['红色警戒','穿越火线','劲舞团','超级玛丽'] } }, } </script>
使用方式
app.vue <template> <div class="container"> <Category title="游戏"> <template scope="xxx"> <ul> <li v-for="(g,index) in xxx.games" :key="index">{{g}}</li> </ul> </template> </Category> <Category title="游戏"> <template scope="{games}"> <ol> <li style="color:red" v-for="(g,index) in games" :key="index">{{g}}</li> </ol> </template> </Category> <Category title="游戏"> <template slot-scope="{games}"> <h4 v-for="(g,index) in games" :key="index">{{g}}</h4> </template> </Category> </div> </template> 子组件: <template> <div class="category"> <h3>{{title}}分类</h3> <slot :games="games" msg="hello">我是默认的一些内容</slot> </div> </template> <script> export default { name:'Category', props:['title'], data() { return { games:['红色警戒','穿越火线','劲舞团','超级玛丽'], } }, } </script>
注意
注意 v-slot 只能添加在 上 (只有一种例外情况),这一点和已经废弃的 slot attribute 不同。