Vue的插槽&作用域插槽

为什么要使用插槽

我们先写一个父组件向子组件传标签的代码

<body>
	<div id="root">
		<child content='<p>world</p>'></child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			props:['content'],
			template:'<div> <p>hello</p> {{content}} </div>'
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>


这里显示的是传递进来的HTML标签,并没有进行渲染。

所以我们将模板修改为:

template:'<div> <p>hello</p> <div v-html="this.content"></div> </div>'


这样做的缺点首先是需要在外面写一个<div>盒子进行包裹。其次,若content内容较多时,比较难阅读。

插槽

什么是插槽

语法:<slot></slot>

作用:将父组件前后标签中的HTML文件渲染插入模板中使用。

接下来我们使用插槽来实现同样的功能。

<body>
    <div id="root">
		<child>
			<h1>world</h1>
		</child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			template:'<div> <p>hello</p> <slot></slot> </div>'
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>


顾名思义,插槽就是将父组件插入的部分传入模板中进行使用。

插槽的一些用法

  • 当使用<slot></slot>标签,但是父组件中没有插入html代码时,标签内的代码将被渲染。
<body>
	<div id="root">
		<child></child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			template:'<div> <p>hello</p> <slot><h1>world</h1></slot> </div>'
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>

  • 使组件内容由子组件设定和外部传入组成

我们希望这个模板由父组件提供页头和页脚,其余部分由自身模板决定。

<body>
	<div id="root">
		<child>
			<div class="header">header</div>
			<div class="footer">footer</div>
		</child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			template:`<div>
					<slot></slot> 
					<div class='content'>content</div>
					<slot></slot>
					</div>`
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>

<<插一句:这里使用的ES6的写法来进行换行书写模板,实现效果不变,但是看着更清晰。>>


出现第一个和第二个<slot>标签都显示了整个插槽俩内容。

当然我们需要让他们一一对应,所以我们给插槽取名字变成具名插槽

<child>
    <div class="header" slot="header">header</div>
    <div class="footer" slot="footer">footer</div>
</child>

使用时也按名用:

Vue.component('child',{
        template:`<div>
            <slot name='header'></slot> 
            <div class='content'>content</div>
            <slot name='footer'></slot>
        </div>`
})

其余部分不变

  • 找不到具名插槽时以默认值为内容
    这里我们将上面代码的第一个插槽去掉
<body>
	<div id="root">
		<child>
			<div class="footer" slot="footer">footer</div>
		</child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			template:`<div>
					<slot name='header'>找不到!</slot> 
					<div class='content'>content</div>
					<slot name='footer'></slot>
					</div>`
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>

作用域插槽

准备代码

我们先写一个子组件,并实现循环输出列表内容的效果

<body>
	<div id="root">
		<child></child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			data:function(){
				return{
					list:[1,2,3,4]					
				}
			},
			template:`<div>
						<ul>
							<li v-for="item of list">{{item}}</li>
						</ul>
					  </div>`
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>

实现外部控制形式的功能

我们现在希望能实现由外部决定循环输出数组的格式,而不是都按<li>输出。

  1. 首先修改子组件模板内部为插槽形式:

使用 <slot> 语句,并将item值绑定在val上

template:`<div>
            <ul>
                <slot v-for="item of list" :val=item>
                </slot>
            </ul>
         </div>`
  1. 父组件中写作用域插槽
    作用域插槽必须是一个<template>开头和结尾的内容
<child>
    <template slot-scope="props">
    </template>
</child>

在<child>中套一个 <template></template> ,这是固定写法,同时需要在前标签中写入slot-scope="props",意为子组件的值储存在"prop"中,此处“props”仅仅是个属性名字,可以自己定义,其作用是接受子组件中的绑定值。

  1. 将从子组件获取的值使用
<child>
    <template slot-scope="props">
        <h1>it's {{props.item}}</h1>
    </template>
</child>

这样效果就完成了

  1. 完整代码:
<body>
	<div id="root">
		<child>
			<template slot-scope="props">
				<h1>it's {{props.val}}</h1>
			</template>
		</child>
	</div>

	<script type="text/javascript">
		Vue.component('child',{
			data:function(){
				return{
					list:[1,2,3,4]					
				}
			},
			template:`<div>
						<ul>
							<slot v-for="item of list" :val=item>
							</slot>
						</ul>
					  </div>`
		})

		var vm =new Vue({
			el:'#root',
		})
	</script>
</body>

最后完整捋一遍

首先将子组件写成插槽,然后将子组件中储存的值绑定在val上,我们在外部组件(父组件)上写slot-scope="props",使子组件上绑着的 val(来自list的item数据)储存在父组件定义的属性 "props"中,并通过props.val使用。

然后我们在父组件中说明以某种形式展示子组件存储在list内的值,并传递给插槽。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值