Vue中的插槽和作用域插槽

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

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

  1.  
    <div id="root">
  2.  
    <child>
  3.  
    需要插槽才能渲染的内容
  4.  
    <p>Dell</p>
  5.  
    <p>Lee</p>
  6.  
    </child>
  7.  
    </div>
  8.  
    <script>
  9.  
    Vue.component('child',{
  10.  
    template: `<div>
  11.  
    <p>这是子组件中正常渲染的内容</p>
  12.  
    </div>`
  13.  
    }
  14.  
    )
  15.  
    var vm=new Vue({
  16.  
    el:'#root'
  17.  
    })
  18.  
    </script>

结果:

 

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

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

结果: 

2、插槽默认内容 

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

  1.  
    父组件没有提供插槽内容
  2.  
    <div id="root">
  3.  
    <child></child>
  4.  
    </div>
  5.  
    <script>
  6.  
    Vue.component('child',{
  7.  
    template:'<div><slot>defalut value</slot></div>
  8.  
    }
  9.  
    )
  10.  
    var vm=new Vue({
  11.  
    el:'#root'
  12.  
    })
  13.  
    </script>

  

  1.  
    父组件提供插槽内容
  2.  
    <div id="root">
  3.  
    <child>
  4.  
    <p>Hello</p>
  5.  
    </child>
  6.  
    </div>
  7.  
    <script>
  8.  
    Vue.component('child',{
  9.  
    template:'<div><slot>defalut value</slot></div>
  10.  
    }
  11.  
    )
  12.  
    var vm=new Vue({
  13.  
    el:'#root'
  14.  
    })
  15.  
    </script>

3、具名插槽 

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

使用方法如下例

  1.  
    <div id="root">
  2.  
    <child>
  3.  
    <header slot="header">header</header>
  4.  
    <footer slot="footer">footer</footer>
  5.  
    </child>
  6.  
    </div>
  7.  
    <script>
  8.  
    Vue.component('child',{
  9.  
    template:`<div>
  10.  
    <slot name="header">default header</slot>
  11.  
    <div>content</div>
  12.  
    <slot name="footer">default footer</slot>
  13.  
    </div>`
  14.  
    }
  15.  
    )
  16.  
    var vm=new Vue({
  17.  
    el:'#root'
  18.  
    })
  19.  
    </script>

结果:

4、作用域插槽 

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

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

  1.  
    <div id="root">
  2.  
    <child></child>
  3.  
    <child></child>
  4.  
    </div>
  5.  
    <script>
  6.  
    Vue.component('child',{
  7.  
    data: function(){
  8.  
    return {
  9.  
    list:[1,2,3,4]
  10.  
    }
  11.  
    },
  12.  
    template: '<div><ul><li v-for="value in list">{{value}}</li></ul></div>',
  13.  
    })
  14.  
    var vm=new Vue({
  15.  
    el: '#root'
  16.  
    })
  17.  
    </script>

结果: 

 

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

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

  1.  
    <div id="root">
  2.  
    <child>
  3.  
    <template slot-scope="props"><!--定义一个插槽,该插槽必须放在template标签内-->
  4.  
    <li>{{props.value}}</li><--!定义使用渲染方式-->
  5.  
    </template>
  6.  
    </child>
  7.  
    <child>
  8.  
    <template slot-scope="props">
  9.  
    <h1>{{props.value}}</h1><!--定义不同的渲染方式-->
  10.  
    </template>
  11.  
    </child>
  12.  
    </div>
  13.  
    <script>
  14.  
    Vue.component('child',{
  15.  
    data: function(){
  16.  
    return {
  17.  
    list:[1,2,3,4]
  18.  
    }
  19.  
    },
  20.  
    template: `<div>
  21.  
    <ul>
  22.  
    <slot v-for="value in list" :value=value>//使用slot占位
  23.  
    </slot>
  24.  
    </ul>
  25.  
    </div>`
  26.  
    })
  27.  
    var vm=new Vue({
  28.  
    el: '#root'
  29.  
    })
  30.  
    </script>

 结果

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

 slot-scope

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

原文地址:https://www.cnblogs.com/1549983239yifeng/p/14277296.html