Vue.js组件——slot杂记

懒得再写一遍,直接把我的笔记截图放上来了。

这里写图片描述

这里写图片描述

截图的内容其实是自己写的测试代码最后的效果,下面把测试代码贴出来:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Vue 组件slot</title>
        <script src="../js/vue.min.js"></script>
    </head>
    <body>
        <div id="app1">
            <p>开始Vue.js slot的学习</p>
            <p>下面使用一个子组件component-a,在组件的模板(template)中设置slot</p>
            <component-a>
                <!-- <p>看这部分内容是不是会将组件中的slot的内容替换掉</p> -->
            </component-a>
        </div>
        <p>----------------------------------------------</p>
        <p>书上只讲了只有一个不具名的slot的例子,这里试一下多个不具名的slot会发生什么。</p>
        <div id="app2">
            <component-b>
                <p>见证奇迹的时刻,多个不具名的slot的到底会怎样?</p>
            </component-b>
        </div>
        <h4>在上面的例子中,我只写了一个“见证奇迹的时刻,多个不具名的slot的到底会怎样?”</h4>
        <h4>但是在页面中显示了两行文字,因为在component-b组件的模板中定义了两个不具名的slot。</h4>
        <h4>那么,结论就出来了,如果在组件中定义了多个不具名的slot,父组件会把所有没有指定slot属性的内容挨个插入组件中的slot里面去。所以,在实际应用中,还是最多只定义一个不具名的slot</h4>
        <p>----------------------------------------------</p>
        <h2>具名slot</h2>
        <p>按照我的理解,具名slot的作用在于将不同的内容插入到不同的slot中去,最常见的例子是一个网页中,分为了头部、内容区域、脚部,各个部分应用不同的样式。</p>
        <p>下面是一个具名slot的例子</p>
        <div id="app3">
            <component-c>
                <div slot="footer">页面脚部</div>
                <h3 slot='header'>标题</h3>
                <p>这里是没有指定slot属性的正文部分</p>
                <p slot="container">这是指定了slot的正文部分</p>

            </component-c>
        </div>
        <h4>发现了一个小现象,就是不管在父组件中按什么顺序写,最终渲染在浏览器中的还是按子组件的顺序来</h4>
        <p>----------------------------------------------</p>
        <h2>作用域插槽</h2>
        <p>作用域插槽是一种特殊的slot。怎么个特殊法呢?</p>
        <h5>首先,它的写法特殊:</h5>
        <p>在HTML代码中,在子组件中使用template标签,并且给template标签一个scope属性</p>
        <h5>其次,它的作用特殊:</h5>
        <p>它可以通过scope属性,获取子组件插槽中的数据</p>
        <p>按我的理解,这个scope属性的值是一个对象,这个对象的属性就是子组件中slot的所有的属性</p>
        <p>下面是例子:</p>
        <div id="app4">
            <p>这是component-d标签外的内容</p>
            <component-d>
                <p>这是template标签外的内容</p>
                <template scope="props">
                    <p>这是template标签里面的内容,但是没有使用scope属性</p>
                    <p>下面的p标签只包含scope属性的内容</p>
                    <p>{{ props.msg }}</p>
                </template>
            </component-d>
        </div>
        <p>下面是另一个例子:列表组件</p>
        <div id="app5">
            <my-list :books="books">
                <template slot="book" scope="books">
                    <li>{{ books.bookName }}</li>
                </template>
            </my-list>
        </div>
        <p>----------------------------------------------</p>

        <script> 
            Vue.component('component-a',{
                template:'<div><slot><div>如果父组件没有插入内容,我将作为默认出现</div></slot></div>'
            });

            Vue.component('component-b',{
                template:'<div>\
                            <slot>\
                                <div>\
                                    1)如果父组件没有插入内容,我将作为默认出现\
                                </div>\
                            </slot>\
                            <slot>\
                                <div>\
                                    2)如果父组件没有插入内容,我将作为默认出现\
                                </div>\
                            </slot>\
                        </div>'
            });

            Vue.component('component-c',{
                template:'<div>\
                            <slot name="header">\
                                <div>\
                                    1)如果父组件没有插入内容,我将作为默认出现\
                                </div>\
                            </slot>\
                            <slot name="container">\
                                <div>\
                                    2)如果父组件没有插入内容,我将作为默认出现\
                                </div>\
                            </slot>\
                            <slot>\
                                <div>\
                                    4)如果父组件没有插入内容,我将作为默认出现(前面3个都是假的默认值,他们都有name属性)\
                                </div>\
                            </slot>\
                            <slot name="footer">\
                                <div>\
                                    3)如果父组件没有插入内容,我将作为默认出现\
                                </div>\
                            </slot>\
                        </div>',
                mounted:function(){
                    var header = this.$slots.header;
                    var main = this.$slots.container;
                    var footer = this.$slots.footer;
                    var sss = this.$slots.default;
                    console.log(sss);
                    console.log(footer[0].elm.innerHTML);
                }
            });

            Vue.component('component-d',{
                data:function(){
                  return {
                      msg:'子组件中的data中msg的内容'
                  }  
                },
                template:'<div>\
                            <slot :msg="msg"></slot>\
                          </div>'
            });

            Vue.component('my-list',{
                props:{
                    books:{
                        type:Array,
                        default:function(){
                            return [];
                        }
                    }
                },
                template:'\
                <ul>\
                    <slot name="book" v-for="book in books" :book-name="book.name"></slot>\
                </ul>'
            });

            var app1 = new Vue({
                el:'#app1'
            });

            var app2 = new Vue({
                el:'#app2'
            });

            var app3 = new Vue({
                el:'#app3'
            });

            var app4 = new Vue({
                el:'#app4'
            });

            var app5 = new Vue({
                el:'#app5',
                data:{
                    books:[
                        {name:'《Vue.js实战》'},
                        {name:'《JavaScript高级程序设计》'},
                        {name:'《Node.js实战》'},
                        {name:'《深入浅出Node.js》'}
                    ]
                }
            });

        </script>
    </body>
</html>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值