十三、插槽

插槽

(1.)插槽内容
    <template id="componentThree">
        <p>
	        我是子组件模板
	        <slot></slot>
        </p>
    </template>
    <div id='app'>
        <component-three :title = 'doc.title'>
            <h1>{{doc.title}}</h1>
        </component-three>
    </div>
    
    <script>
       var ComponentC = {
            props:['title'],
           data:function(){
               return {}
           },
           template:"#componentThree"
       }
       new Vue({
           el:'#app',
            data:{
                doc:{
                    title: "我是插槽的内容"
                    }
            },
            components:{
                'component-three':ComponentC
            }
       })
    </script>
  • 只要在子组件模板中加入<slot></slot>标签,就可以在使用子组件时在其中加入任何模板代码,vue都会将其渲染出来,如果不加则无论输入什么都不会出来。
  • 子组件模板中加入<slot></slot>标签,如下:加入插槽标签
  • 子组件模板中不加<slot></slot>标签,如下:不加插槽标签
    总之一句话加了一切好说,不加耶稣也救不了它。
(2.)编译作用域
  • 当你想在一个插槽中使用数据时,它是不能访问自组件的作用域的,比如上面的代码中插入的元素如果想使用<component-three :title = 'doc.title'>中的title它是访问不到的。
  • vue规则:

父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。

(3.)后备内容
  • 它只在子组件中没有插入任何内容时会被渲染,例:
    <template id="componentThree">
        <div>
            <p>happy day!!</p>
            <slot>插槽后备内容</slot>
        </div>
    </template>
    <div id='app'>
        <component-three :title = 'doc.title'>
        </component-three>
    </div>
    
    <script>
       var ComponentC = {
            props:['title'],
           data:function(){
               return {}
           },
           template:"#componentThree"
       }
       new Vue({
           el:'#app',
            data:{
                doc:{
                    title: "我是插槽的内容"
                    }
            },
            components:{
                'component-three':ComponentC
            }
       })
    </script>
  • 没有向子组件中插入任何内容:子组件中没有插入任何内容
  • 如果子组件中插入一个<h1>标签:插入后,内容改变
(4.)具名插槽
  • 有时需要实现多个插槽分块插入的需求,插入的内容有相对应的模块,对此<slot>标签中有name属性,这个属性可以用来定义额外的插槽,例:
<template id="componentThree">
        <div>
            <p>happy day!!</p>
            <slot name="head">我是头部插槽</slot>
            <slot name="foot">我是尾部插槽</slot>
        </div>
    </template>
    <div id='app'>
        <component-three :title = 'doc.title'>
           <h1 slot="foot">one two three!!</h1>
           <h4 slot="head">we have time</h4>
        </component-three>
    </div>

    <script>
       var ComponentC = {
            props:['title'],
           data:function(){
               return {}
           },
           template:"#componentThree"
       }
       new Vue({
           el:'#app',
            data:{
                doc:{
                    age:45,
                    title: "我是插槽的内容"
                    }
            },
            components:{
                'component-three':ComponentC
            }
       })
    </script>
  • 子组件插入的元素通过slot name的属性用slot="name"来匹配对应的插槽。
(5.)具名插槽v-slot(船新版本)
  • 上面使用的 slot="xx",在在2.6.0+ 中已弃用。
  • 新版v-slot注意事项:
  • (1.) 匿名插槽在新语法下,默认指向default ,例:v-slot:default
  • (2.) 在旧版本中slot="xxx"的情况下,可以挂载在非 template标签上,如:<h1 slot="foot">one two three!!</h1>,新版中必须使用<template>标签,如:<template v-slot:foot>one two three!!</template>
  • (3.)v-slot:tit可缩写为#tit
<!--用新的v-slot替换旧的slot="xx"-->
 <div id='app'>
        <component-three :title = 'doc.title'>
           <template v-slot:foot>one two three!!</template>
           <template v-slot:head>we have time</template>
        </component-three>
    </div>
(6.)作用域插槽(slot-scope废弃)
  • 作用:父组件访问子组件内部数据.
  • (6.1) 废弃的 slot-scope的作用域插槽:
    + 1. 语法:slot-scope="slotProps"
    + 2. 例:
<template id="componentThree">
        <div>
            <slot name="footer" :msg="msg"></slot> 
             <slot slot="headed">今天天气很不错!!!</slot>
        </div>
    </template>
    <div id='app'>
        <component-three>
           <div slot='footer' slot-scope="slotProps">
            {{slotProps.msg}}
           </div>
           <h1 name='headed'></h1>
        </component-three>
    </div>
    
   
    <script>
       var ComponentC = {
            props:['title'],
           data:function(){
               return {
                   msg: 'fffffff'
               }
           },
           template:"#componentThree"
       }
       new Vue({
           el:'#app',
            data:{
                doc:{
                    age:45,
                    title: "我是插槽的内容",
                    msg:'hahahahah'
                    }
            },
            components:{
                'component-three':ComponentC
            }
       })
    </script>
  • slot元素上任意定义一个属性,如msg,在使用子组件时添加slot-scope属性如slot-scope="slotProps"(slotProps可为任意名字)接着显示,{{slotProps.msg}}发现出现了在子组件定义的msg的值。
  • 这样插槽就可以使用父组件的值。
  • 在子组件中放入父组件想让显示的内容。
  • 例:
<template id="componentThree">
<div>
	<ul>
		<li v-for="items in personDate">
			<slot name="footer" :item="items"></slot>
		</li>
	</ul>
</div>
</template>
<div id="app">
	<component-three :person-date="personDate">
		<div slot="footer" slot-scope="slotProps">
			{{slotProps.item.id}}--{{slotProps.item.name}}--{{slotProps.item.sex}}
		</div>
	</component-three>
</div>
<script>
var componentC = {
	props:["personDate"],
	data:function(){
		return {}
},
	template:"#componentThree"
}
new Vue({
	el:"#app",
	data:{
	personDate:[
		{id:1,name:'花花',sex:'女',age:18},
        {id:2,name:'小明',sex:'男',age:32},
        {id:3,name:'小红',sex:'女',age:45},
        {id:4,name:'小李',sex:'男',age:12},
        {id:5,name:'小黄',sex:'女',age:24},
        {id:6,name:'伟伟',sex:'男',age:67}
		]
	},
	components:{
		"componentThree":componentC
	}
})
</script>
  • 以上为完整的父子元素传递代码:主要流程
  • 1. 父组件将自身数据通过props传递给子组件。
  • 2. 子组件将数据传给插槽,并暴露给父组件接口,如::item="items"
  • 3.父组件调用子组件的插槽slot接口和数据,如:slot-scope="slotProps"
(7.)作用域插槽(船新版本)
<!--主要变化在子组件使用中-->
<div id="app">
	<component-three :person-date="personDate">
		<template #footer="slotProps">
			{{slotProps.item.id}}--{{slotProps.item.name}}--{{slotProps.item.sex}}
		</template>
	</component-three>
</div>
  • 其中<div>标签变为<template>#v-slot简写形式。也可写为v-slot:footer="slotProps"
(7.)解构插槽prop

作用域插槽的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里

  • 这意味着 v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JavaScript 表达式。如:
<current-user v-slot="{ user }">
  {{ user.firstName }}
</current-user>
  • 它同样开启了 prop 重命名等其它可能,如:
<current-user v-slot="{ user: person }">
  {{ person.firstName }}
</current-user>
  • 甚至可以定义后备内容,用于插槽 prop 是 undefined 的情形:
<current-user v-slot="{ user = { firstName: 'Guest' } }">
  {{ user.firstName }}
</current-user>
(8.)动态插槽名
  • 动态指令参数也可以用在 v-slot 上,来定义动态的插槽名如:
<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值