Vue中的插槽和作用域插槽

本文深入讲解Vue中的插槽概念,包括基本插槽的使用、默认内容的设定、具名插槽的应用以及作用域插槽的高级操作。通过实例演示如何在父组件与子组件间传递内容,实现更灵活的组件复用。

1、Vue中插槽的作用和使用方法

定义一个名child子组件,为该子组件添加内容应该在子组件的template中定义,直接在父组件的<child>标签中定义的内容不会被渲染,如下例。

<div id="root">
        <child>
            需要插槽才能渲染的内容
            <p>Dell</p>
            <p>Lee</p>
        </child>
    </div>
    <script>
        Vue.component('child',{
            template: `<div>
                            <p>这是子组件中正常渲染的内容</p>                            
                         </div>`
            }
        )
        var vm=new Vue({
            el:'#root'
        })
    </script>

结果:

 

      使用插槽就能解决这个问题。在子组件template中加入<slot>元素占位,便能渲染父组件<child>标签下的内容,对上例的子组件修改为:

 Vue.component('child',{
            template: `<div>
                            <p>这是子组件中正常渲染的内容</p>
                            <slot></slot>
                         </div>`
            }
        )

结果: 

2、插槽默认内容 

插槽可以提供一个默认内容,如果如果父组件没有为这个插槽提供了内容,会显示默认的内容。如果父组件为这个插槽提供了内容,则默认的内容会被替换掉

父组件没有提供插槽内容   
 <div id="root">
        <child></child>
    </div>
    <script>
        Vue.component('child',{
            template:'<div><slot>defalut value</slot></div>
            }
        )
        var vm=new Vue({
            el:'#root'
        })
    </script>

  

父组件提供插槽内容   
 <div id="root">
        <child>
           <p>Hello</p>
        </child>
    </div>
    <script>
        Vue.component('child',{
            template:'<div><slot>defalut value</slot></div>
            }
        )
        var vm=new Vue({
            el:'#root'
        })
    </script>

3、具名插槽 

当需要多个插槽时,可以使用<slot>的特性:name。这个特性可以用来定义额外的插槽

使用方法如下例

 <div id="root">
        <child>
            <header slot="header">header</header>
            <footer slot="footer">footer</footer>
        </child>
    </div>
    <script>
        Vue.component('child',{
            template:`<div>
                            <slot name="header">default header</slot>
                            <div>content</div>
                            <slot name="footer">default footer</slot>
                        </div>`
            }
        )
        var vm=new Vue({
            el:'#root'
        })
    </script>

结果:

4、作用域插槽 

可以先看一个例子,以便更好的理解作用域插槽的作用

在子组件中使用v-for创建一个列表循环,然后在父组件中通过子组件标签child调用,如下例。

 <div id="root">
        <child></child>
        <child></child>
    </div>
    <script>
        Vue.component('child',{
            data: function(){
                return {
                    list:[1,2,3,4]
                }
            },
            template: '<div><ul><li v-for="value in list">{{value}}</li></ul></div>',
        })
        var vm=new Vue({
            el: '#root'
        })
    </script>

结果: 

 

 调用了两次child组件,因为调用的是同一个子组件,所以显示的内容完全一样。如何在每次调用时能有各自的渲染效果?这就是作用域插槽的用武之地。

作用域插槽就是父组件在调用子组件的时候给子组件传了一个插槽,这个插槽为作用域插槽,该插槽必须放在template标签里面,同时声明从子组件接收的数据放在一个自定义属性内,并定义该数据的渲染方式。通过下列展示作用域插槽的使用方式:

<div id="root">
        <child>
            <template slot-scope="props"><!--定义一个插槽,该插槽必须放在template标签内-->
                <li>{{props.value}}</li><--!定义使用渲染方式-->
            </template>
        </child>
        <child>
            <template slot-scope="props">
                <h1>{{props.value}}</h1><!--定义不同的渲染方式-->
            </template>
        </child>
    </div>
    <script>
        Vue.component('child',{
            data: function(){
                return {
                    list:[1,2,3,4]
                }
            },
            template: `<div>
                            <ul>
                                <slot v-for="value in list" :value=value>//使用slot占位
                                </slot>
                            </ul>
                        </div>`
        })
        var vm=new Vue({
            el: '#root'
        })
    </script>

 结果

通过上例可知,使用作用域插槽后,两次调用子组件可以定义不同的渲染方式。

 slot-scope

如果一个 JavaScript 表达式在一个函数定义的参数位置有效,那么这个表达式实际上就可以被 slot-scope 接受。

Vue2中的插槽分为默认插槽、具名插槽作用域插槽三种类型。 默认插槽是指没有被包裹在具名插槽中的内容,可以通过在父组件中使用<slot>标签来使用默认插槽。 具名插槽是指被包裹在<template>标签中,并且带有name属性的内容。可以在父组件中使用<slot>标签的name属性来使用具名插槽作用域插槽是指可以将子组件中的数据传递到父组件中进行处理的插槽。可以通过在子组件中使用<slot>标签,并且在标签中使用slot-scope属性来定义作用域插槽。在父组件中使用<template>标签,并且在标签中使用v-slot属性来使用作用域插槽。 下面是一个使用具名插槽作用域插槽的例子: ```html <!-- 子组件 --> <template> <div> <h2>子组件</h2> <slot name="header"></slot> <ul> <li v-for="item in list" :key="item">{{ item }}</li> </ul> <slot name="footer" :list="list"></slot> </div> </template> <script> export default { name: 'ChildComponent', props: { list: { type: Array, default: () => [] } } } </script> <!-- 父组件 --> <template> <div> <h2>父组件</h2> <ChildComponent :list="list"> <template v-slot:header> <h3>这是子组件的头部</h3> </template> <template v-slot:footer="slotProps"> <h3>这是子组件的尾部</h3> <p>列表长度:{{ slotProps.list.length }}</p> </template> </ChildComponent> </div> </template> <script> import ChildComponent from './ChildComponent.vue' export default { name: 'ParentComponent', components: { ChildComponent }, data() { return { list: ['item1', 'item2', 'item3'] } } } </script> ```
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值