Vue slot(插槽)

前言

  插槽是组件的一部分,当时做项目的时候使用到了插槽,并不是很懂,vue官网也没有说明的很清楚,只是说vue实现了一套内容分发的api,\元素承载分发内容的出口。也就是说插槽是用来分发内容的。那就举个栗子说明一下:

// app
<component-a>
   这是插槽内容
</component-a>

// component-a html
<div>
    hello,word!
</div>

  上面app中放了一个component-a组件,组件的内容是下面的,这样在浏览器中渲染出来的结果是什么呢?结果是只会渲染出组件中的内容。app中组件标签里的内容被抛弃了。我们在组件中加一下slot,会发现之前写在组件内的内容出来了,这就是插槽的作用,可以分发内容。意思就是如果不使用插槽,在组件标签内写的任何内容都是不会生效的。

<body>
    <div id="app">
        <component-a>
            这是插槽内容
         </component-a>
    </div>
</body>
    <script>
        Vue.component('component-a',{
            template: `
            <div>hello,word!<slot></slot></div>
            `
        });

        const app = new Vue({
            el: '#app',
            data() {
                return {};
            }
        });
    </script>

  这个插槽也叫单个插槽。

具名插槽

  具名插槽就是具有名字的插槽,在组件中给插槽取上名字,然后再组件标签内slot属性填上名字,它就会跟组件内的name一一对应。那么没有名字的就是默认插槽了。

<style>
        .border {
            border: 1px solid #e7494b;
        }s
</style>
</head>
<body>
    <div id="app">
        <component-a>
            <div>
                默认插槽的内容
            </div>
            <template slot="slota">
                插槽a的内容
            </template>
            <template slot="slotb">
                插槽b的内容
            </template>
         </component-a>
    </div>
</body>
    <script>
        Vue.component('component-a',{
            template: `
            <div>
              <h2>具名插槽</h2>
              <slot></slot>
              <div class="border"></div>
              <slot name="slota"></slot>
              <div class="border"></div>
              <slot name="slotb"></slot>
            </div>
            `
        });

        const app = new Vue({
            el: '#app',
            data() {
                return {};
            }
        });
    </script>

作用域插槽

  其实上面两种插槽都很简单,一个就是默认插槽不进行命名,具名插槽就是给个名字,然后标签内的内容就会和组件中的名字一一对应,分发内容。

  作用域插槽就是可以把组件标签内的数据在组件元素中使用,我也不知道这样解释合不合理,先看个简单的例子把。

<body>
    <div id="app">
        <component-a>
            <template slot-scope="name">
                {{ name }}
            </template>
        </component-a>
    </div>
</body>
    <script>
        Vue.component('component-a',{
            template: `
            <div>
                <slot say="hello"></slot>
            </div>
            `
        });

        const app = new Vue({
            el: '#app',
            data() {
                return {
                };
            }
        });
    </script>

  在slot元素上定义一个属性,然后在template添加slot-scope,我们将结果放在标签内展示出来,会看到一个slot属性和值的键值对,这就是作用域插槽。

  再来看看这个例子:

<body>
    <div id="app">
        <component-a :lists="list">
            <template slot-scope="name">
                {{ name }}
            </template>
        </component-a>
    </div>
</body>
    <script>
        Vue.component('component-a',{
            props: ['lists'],
            template: `
            <div>
               <ol>
                 <li v-for="item in lists">
                    <slot :data="item"></slot>
                 </li>
               </ol>
            </div>
            `
        });

        const app = new Vue({
            el: '#app',
            data() {
                return {
                    list: [
                        { no: 1, name: '张三' },
                        { no: 2, name: '李四' },
                        { no: 3, name: '王五' },
                        { no: 4, name: '陈六' },
                        { no: 5, name: '吴七' }
                    ]
                };
            }
        });
    </script>

  如果你用过elementui,就会觉得很熟悉,table就是这样的。

  作用域插槽还是比较好用的,这篇文章也只是简单的介绍了插槽的使用和给了一些例子来方便说明。