zoukankan      html  css  js  c++  java
  • slot内容分发

    vue实现了一套内容分发的API,这套API基于当前的web components规范草案,将<slot>元素作为承载分发内容的出口。

    在前面的父子组件中,我们提到过,在vue中,组件实例的作用域是孤立的,默认情况下,父子组件的数据是不能共享的。所以子组件的内容应当写在子组件里面,父组件的内容应该写在父组件里面,下面的这种情况。父组件的内容将会被默认丢弃。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="box">
            <aaa></aaa>
        </div>
    
        <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb>
                    <p>测试内容1</p>
                    <p>测试内容2</p>
                    <p>测试内容3</p>
                </bbb>
              </div>
        </template>
        <script>
            var vm=new Vue({
                el:'#box',
                data:{
                    a:'aaa'
                },
                components:{
                    'aaa':{
                        data(){
                            return {
                                msg2:'我是父组件的数据'
                            }
                        },
                        template:'#aaa',
                        components:{
                            'bbb':{
                                template:`
                                    <div class="child">
                                        <p>子组件</p>
                                    </div>
                                    `,
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

    此时,如果我们希望上面的内容不被丢弃,就需要使用到一个特殊的<slot>元素作为元素内容的插槽。

    匿名slot

    当子组件模板中只有一个没有属性的slot时,父组件整个的内容都将插入到slot所在的位置,直接替换掉slot标签。需要注意的是,匿名slot最多只能有一个,多个匿名slot会导致程序报错。

    <div id="box">
            <aaa></aaa>
        </div>
    
        <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb>
                    <p>测试内容1</p>
                    <p>测试内容2</p>
                    <p>测试内容3</p>
                </bbb>
              </div>
        </template>
        <script>
            var vm=new Vue({
                el:'#box',
                data:{
                    a:'aaa'
                },
                components:{
                    'aaa':{
                        data(){
                            return {
                                msg2:'我是父组件的数据'
                            }
                        },
                        template:'#aaa',
                        components:{
                            'bbb':{
                                template:`
                                    <div class="child">
                                        <p>子组件</p>
                                        <slot></slot>
                                    </div>
                                    `,
                            }
                        }
                    }
                }
            });
        </script>

    我们可以在slot标签中添加任何内容作为默认值,在上面我们说的是,父组件的整个内容会替换到slot,所以,如果父组件中是有需要插入的内容是,这些默认值会随着slot被替换而替换掉,只有当父组件里面没有内容时,才会显示这些默认值。

      <div id="box">
            <aaa></aaa>
        </div>
        <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb></bbb>
              </div>
        </template>
        <script>
            var vm=new Vue({
                el:'#box',
                data:{
                    a:'aaa'
                },
                components:{
                    'aaa':{
                        data(){
                            return {
                                msg2:'我是父组件的数据'
                            }
                        },
                        template:'#aaa',
                        components:{
                            'bbb':{
                                template:`
                                    <div class="child">
                                        <p>子组件</p>
                                        <slot><div>我是默认值</div></slot>
                                    </div>
                                    `,
                            }
                        }
                    }
                }
            });
        </script>

    实名slot

     有匿名slot,自然就像到了不是匿名的slot,这一类slot可以用一个特殊的属性name来配置内容分发,根据name来匹配内容片段中有对应slot特性的元素。可以有多个不同名字的slot同时存在,并且此时也可以有一个匿名slot,作为找不到匹配的内容片段的备用插槽。

    <div id="box">
            <aaa></aaa>
        </div>
    
        <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb>
                    <p slot="my-header">我是头部</p>
                    <p slot="my-footer">我是尾部</p>
               <p slot="my-test">我是测试的</p>
                    <p>我是主体1</p>
                    <p>我是主体2</p>
                    <p>我是主体3</p>
                </bbb>
              </div>
        </template>
        <script>
            var vm=new Vue({
                el:'#box',
                data:{
                    a:'aaa'
                },
                components:{
                    'aaa':{
                        data(){
                            return {
                                msg2:'我是父组件的数据'
                            }
                        },
                        template:'#aaa',
                        components:{
                            'bbb':{
                                template:`
                                    <div class="child">
                                        <p>子组件</p>
                                        <slot name="my-header">头部默认值</slot>
                                        <slot name="my-body">主体默认值</slot>
                                        <slot name="my-footer">尾部默认值</slot>
                                        <slot></slot>
                                    </div>
                                    `,
                            }
                        }
                    }
                }
            });
        </script>

    我们来分析一下上面代码的执行过程。

    • 首先是名字为"my-header"的slot在父组件中寻找对应的slot,即<p slot="my-header">我是头部</p>并进行渲染。
    • 接着是名字为"my-body"的slot在父组件中寻找对应的slot,并没有找到,所以显示的是自己的默认值。
    • 然后是名字为"my-footer"的slot在父组件中寻找,同第一步一样。
    • 此时,所有实名的slot都已经寻找完了,如果没有匿名slot,那么父组件中剩余没有匹配的内容都会被丢弃,但这个里面是有一个匿名slot的,所以它会寻找到父组件中所有不带slot属性的元素,然后替换自己,进行渲染。
    • 最后,在父组件中还有一个有slot属性却没有匹配的slot的元素,将会被丢弃。

    在上面的例子中,当我们将最后的匿名slot删除,那么所有没有slot属性的元素也都会被丢弃。

      

    组件列表

     slot还能被用作一个可以重复使用的模板来渲染列表,此时需要在子组件中将数据传递到slot插槽中,然后在父组件中使用带scope的<template>元素作为模板,其中的scope则是被用来接收从子组件中传递过来的数据,然后就可以实现循环渲染列表了。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>vue</title>
        <script src="./vue.js"></script>
    </head>
    <body>
        <div id="box">
            <aaa></aaa>
        </div>
    
        <template id="aaa">
            <div class="parent">
                <p>父组件</p>
                <bbb>
                    <template slot="item" scope="props">
                        <li>{{ props.text }}</li>
                    </template>
                </bbb>
              </div>
        </template>
        <script>
            var vm=new Vue({
                el:'#box',
                data:{
                    a:'aaa'
                },
                components:{
                    'aaa':{
                        data(){
                            return {
                                msg2:'我是父组件的数据'
                            }
                        },
                        template:'#aaa',
                        components:{
                            'bbb':{
                                template:`
                                     <ul>
                                        <slot name="item" v-for="item in items" :text="item.text">默认值</slot>
                                    </ul>
                                    `,
                                data(){
                                    return{
                                        items:[
                                            {id:1,text:'苹果'},
                                            {id:2,text:'香蕉'},
                                            {id:3,text:'葡萄'},
                                        ]
                                    }
                                }
                            }
                        }
                    }
                }
            });
        </script>
    </body>
    </html>

  • 相关阅读:
    Objective
    Objective
    安排
    ios 类的内部结构
    什么是静态语言,什么是动态语言?
    ios 中的 GCD
    IOS 中的JS
    菱形开合的实现 IOS
    典题
    c++连接数据库 在vc6.0
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/9807547.html
Copyright © 2011-2022 走看看