插槽

插槽的基本使用

插槽可以大大提高组件的可复用性

定义插槽的一大关键字是slot

在组件模板定义中,可以定义<slot></slot>,这样一来,slot标签便可以被替换

<slot></slot>也可定义默认的数据,这样在没有替换时便会显示默认的数据

slot还有一个关键属性:name,用来唯一区分每个slot。如果不设置name属性,那么就会有一个默认的name:default

在调用组件时,如果没有使用v-slot(语法糖:#)绑定slot,那么默认替换的便是没有定义name属性的slot

注意:在一般情况下,使用v-slot绑定时,需要在template中定义;只有在只有一个默认插槽的情况下才可以直接在组件标签上定义

<body>
    <div id="app">
      <cpn>
        <button>touch me!</button>
      </cpn>
      <cpn>
        <template #header>
            <h1>replace header</h1>
        </template>
      </cpn>
      <cpn>
        <template #footer>
            <h1>replace footer</h1>
        </template>
      </cpn>
    </div>

    <template id="cpn">
      <div>
        <slot>default slot</slot>
        <header>
            <slot name="header">default header</slot>
        </header>
        <footer>
            <slot name="footer">default footer</slot>
        </footer>
      </div>
    </template>

    <script src="../vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        components: {
          cpn: {
            template: `#cpn`
          }
        }
      });
    </script>
</body>

作用域插槽

很多时候需要从父组件中使用子组件的数据,这个时候就需要作用域插槽

简单来说,作用域插槽就是获取子组件的数据

这个过程和组件props很相似,只是语法不同

下面这张图很清晰的解释了数据的调用过程

插槽

在上图中,v-slot还可以写成slot-scope,效果是相同的

在调用时,结合基本使用中的name属性可以发现,default是因为没有给slot设置name属性,所以才使用default。那么如果设置了name属性是不是就可以更改default呢,实际操作发现这样是可以的

<body>
    <div id="app">
      <cpn>
        <template #movie="slotProps">
          {{slotProps}}
        </template>
      </cpn>
    </div>

    <template id="cpn">
<!--      <ul>-->
<!--        <li v-for="item in movies">-->
<!--          <slot :item="item"></slot>-->
<!--        </li>-->
<!--      </ul>-->
      <div>
        <h1>this is props</h1>
        <slot name="movie" :movies="movies"></slot>
      </div>
    </template>

    <script src="../vue.js"></script>
    <script>
      const app = new Vue({
        el: '#app',
        components: {
          cpn: {
            template: `#cpn`,
            data() {
              return {
                movies: ['星际穿越', '千与千寻', '哈利波特', '志明与春娇']
              }
            }
          }
        }
      });
    </script>
</body>
上一篇:HashSet扩容机制在时间和空间上的浪费,远大于你的想象


下一篇:一次性讲明白vue插槽slot