首页 > 技术文章 > Vue slot插槽通俗解释

lhx9527 2020-09-18 16:52 原文

slot内容分发是Vue的Api来源

作用域插槽

<div id="app">
    <my-list> {{msg}} </my-list>
</div>
<script>
   Vue.component("my-list", {
       template: `<div><slot></slot></div>`,
        });
   var app = new Vue({
            el: "#app",
            data: {
                msg: "父组件传参",
            },
        });
</script>

父组件里面:把<my-list> {{msg}} </my-list>中的 <my-list> </my-list>当作一个函数占位符,这里具体函数是my-list
{{msg}}当作父组件传给这个函数的参数
<slot></slot>
子组件里面:对应的函数是抽象的,它的效果就是将参数渲染到页面中
现在做几组对照试验:

  1. 子组件中的template中只有 <slot></slot>能接收传参,现将<slot></slot>去掉
<script>
   Vue.component("my-list", {
       template: `<div></div>`,
        });
   var app = new Vue({
            el: "#app",
            data: {
                msg: "父组件传参",
            },
        });
</script>

没有任何值,父组件虽然传参过去了,但是子组件没接收到,所以子组件不显示
那为什么父组件自己不显示呢?
父组件与子组件是分开编译的,所以我认为是子组件产生的html覆盖了父组件的html

  1. 将slot加回到子组件,但是不给子组件这个插槽函数默认参数
<script>
   Vue.component("my-list", {
       template: `<div><p>位置1<slot></slot></p> 位置2<slot></slot><ul><li>位置3<slot></slot></li></ul></div>`,
        });
   var app = new Vue({
            el: "#app",
            data: {
                msg: "父组件传参",
            },
        });
</script>

子组件只有通过才能接收父组件传递的值

  1. 父组件传参与子组件默认参数的PK,我们知道在函数中传递的实参会覆盖掉函数中的默认参数的
<div id="app">
    <my-list> {{msg}} </my-list>
</div>
<script>
   Vue.component("my-list", {
       template: `<div><slot>子组件默认参数</slot></div>`,
        });
   var app = new Vue({
            el: "#app",
            data: {
                msg: "父组件传参",
            },
        });
</script>

结果显示与函数效果一样:传递的实参会击败默认参数,slot也符合API的特性

具名插槽就是带名字的'函数',用slot接收参数时也要加上对应的name
具名插槽不会使用子组件的值
原始只用slot写法:

<div id="app"> 
    <base-layout>
      <div slot = 'header'>
          我是父组件提供的头部
      </div>
      <div>
        我是父组件提供的main部分
      </div>
      <div slot ="footer"></div>
    </base-layout>
  </div>
  <script>
    Vue.component('baseLayout',{
      template:`
        <div class="container">
          <header>
            <slot name="header">我是子组件提供的头部</slot>
          </header>
          <main>
            <slot>我是子组件提供的main</slot>
          </main>
          <footer>
            <slot name="footer">我是子组件提供的尾部</slot>
          </footer>
        </div>
      `
    })
    var vm = new Vue({
      el:"#app",
      data:{
      }
    })
  </script>

新写法:v-slot
注意 v-slot 只能添加在

推荐阅读