Vue插槽(slot)详解

插槽可以分为几点:

  • 插槽的内容
  • 具名插槽
  • 插槽作用域
一.插槽的内容

一句话:插槽内可以是任意内容先看一下下面的代码

<div id="#app">
	<child>Hello World</child>
</div>

<script>
Vue.component('child', {
  template: `
    <div>
    	<slot></slot>
    </div>
  `
});
let vm = new Vue({
	el: "#app",
	data: {}
})
</script>

也就是说,没有插槽的情况下在组件标签内写的内容是不起任何作用的,只有在组件中声明了slot元素后,在组件元素内写的内容就会跑到<slot></slot>中。

二.具名插槽

具名插槽,就是给这个插槽起个名字
例如:在组件中,给三个插槽加上名字,在创建新的组件内,slot属性对应的内容都会和组件中name一一对应,而没有名字的,就是默认插槽。

  <parent>
  
    <template slot="header">
      this is header 
    </template>
    
    <template slot="main">
      this is main
    </template>
    
    <template slot="footer">
      this is footer
    </template>
    
  </parent>
Vue.component('parent', {
  template: `
  <div>
  
    <div style="margin-top: 2em;color: red">
      <slot name="header"></slot>
    </div>
    
    <div style="color: orange ">  
        <slot name="main"></slot>
    </div>
    
    <div style="color: yellow">
        <slot name="footer"></slot>
    </div>
    
  </div>
});

具名插槽vue 2.6+语法展示(Vue 3支持)
自 2.6.0 起具名插槽有所更新,上面那一种方式在所有的 2.x 版本中 slot仍会被支持,但已经被官方废弃且不会出现在 Vue 3 中。
那我们就把上面的例子用2.6.0的新语法写一次

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>插槽基本用法了解
        </title>
        <script src="https://unpkg.com/vue"></script>
    </head>
    <body>
        <div id="app">
            <child>
                <template v-slot:header><!-- 注意和废弃语法slot="header"对比 -->
                    <div class="header">header</div><!-- v-slot不能直接写在标签上,必须写在template,否则渲染不出来 -->
                </template>
                <template #footer><!-- 注意和废弃语法slot="footer"对比 -->
                    <div class="footer">footer</div><!-- v-slot不能直接写在标签上,必须写在template,否则渲染不出来 -->
                </template>
            </child>
        </div>
        <script> 
            Vue.component('child', {
                template:`<div>
                            <slot name="header"></slot>
                            <p>hello</p>
                            <slot name=footer></slot>
                        </div>` // 换成ES6的语法可以换行方便查看
            })
            var vm = new Vue({
                el: "#app"
                
            })
        </script>
    </body>
</html>

注意:就像v-on:可以缩写成@一样,v-slot:也可以缩写成#,所以v-slot:footer可以缩写成#footer
一个不带 name 的 <slot></slot>会带有隐含的名字name=“default”,父组件传的DOM内容如果不写这种v-slot:header具体告知说要找name="header"的插槽,则就会匹配到<slot></slot>不带name的插槽。
注意 v-slot 只能添加在 <template> 上

插槽作用域

话不多说直接上代码:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>作用域插槽
        </title>
        <script src="https://unpkg.com/vue"></script>
    </head>
    <body>
        <div id="app">
            <child>
                <template #myname="myScope"><!-- #myname等同于v-slot:myname,等同于2.5具名插槽旧语法slot="myname" -->
                    <h1>{{myScope.myItem}}</h1>
                </template>
                <template v-slot="myScope1"><!-- 注意这里是v-slot="myScope1"不是slot="myScope1",要和具名插槽的旧语法区别开 -->
                    <h2>{{myScope1.myItem}}</h2>
                </template>
            </child>
        </div>
        <script> 
            Vue.component('child', {
                data() {
                    return {
                        list: [1, 2, 3, 4]
                    }
                },
                template: `<div>
                                <ul>
                                    <slot v-for="item of list"
                                    :myItem=item>
                                    </slot>
                                    <slot name="myname" :myItem=list></slot>
                                </ul>
                           </div>`
            })
            var vm = new Vue({
                el: "#app"
            })
        </script>
    </body>
</html>

运行结果:
在这里插入图片描述
在上一个例子的基础上需要再解释一下
旧语法slot-scope="myScope"等同于新语法v-slot="myScope"name默认就是default
#myname="myScope"v-slot:myname="myScope"的简写,而v-slot:myname是Vue2.5中具名插槽slot="myname"的简写,#myname="myScope"就是匹配namemyname的插槽slot,并取别名为"myScope",可以通过"myScope"去操作slot上绑定的数据
v-slot="myScope1"等同于v-slot:default=“myScope1”,而插槽<slot>不写name则默认name=“default”,所以也可以缩写成#default=“myScope1”。匹配默认插槽不能直接#,至少加上#default,否则就会如下报错
记得这个标签上的name一定要小写!否则渲染不出来。

有人会问,应该是数组在前,列表在后呀,记得渲染顺序以插槽的位置为准,不是根据父作用域的template顺序判断,这里子组件的第一个绑定的是for循环的每条数据,第二个绑定的才是list!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值