017 vue的插槽的使用

[A] slot插槽

    在开发中,我们经常遇到一个模块中大部分内容相同,部分内容不一样的情况,这个模块可以写成一个组件,

    组件中相同的内容保留,不同的内容暴露在组件预留的插槽中,即可实现最优化代码。

[B] 组建中插槽的使用

  1. 让我们封装额组件更具有拓展性

  2. 让使用者可以决定组件内部的一些内容到底展示什么

[C] 插槽的基本使用方法

  1. 在组件模板中预留插槽

    示例代码:

                        <template>

                            <div>

                                这是组件1

                                <input type="tetx">

                                <slot></slot>       // 预留一个插槽

                            </div>

                        </template>
View Code

    【注】此外,slot插槽中也可以写默认值,当HTML页面中未在插槽中填写内容时,将显示默认内容

                            如: <slot><span>好啦</span></slot>

  2. 在调用组件时,向插槽中加入自定义内容

                    如:

                        <div id="app">

                            <cpn><button>取消啦</button></cpn>

                                // 这个按钮将替换原模板中的slot标签

                            <cpn></cpn>

                            <cpn></cpn>

                        </div>
View Code

[D] 具名插槽

    在一个组件中,我们可以改变组件的多个地方,这里我们就需要在一个组件中加入多个插槽,

    此时,我们需要给组件中的每个插槽设置一个name属性,以便于在html中在特定的那个插槽中填写内容,

    这些有name属性的插槽,我们称之为具名插槽

  具名插槽的使用方法:

                    1. 在组件模板中加入多个插槽,并给每个插槽设置不同的name属性

        示例代码:

                            <template>
                                <div>
                                    这是组件1
                                    <input type="tetx">
                                    <slot name = "left">左边</slot>
                                    <slot name = "center">中间</slot>
                                    <slot name = "right">右边</slot>
                                </div>
                            </template>
View Code

     

      2. 在html页面中使用组件时,在添加的内容的外标签红加入slot属性,指定要添加到的那个插槽

        示例代码:

                            <div id="app">
                                <cpn><span slot="center">修改后的</span></cpn>
                            </div>
View Code

[E] 编译作用域

                    一个组件在使用时,会调用一些属性值,但是它只能调用自己的属性值,即作用域在本组件内。

  编译作用域的官方准则:

    父组件模板的所有东西都会在父级作用域内编译;

    子组件模板的所有东西都会在子级作用域内编译;

  案例1:

                    <body>
                        // 1. html页面元素
                        <div id="app">
                            <cpn v-show="isshow"></cpn>
                            // 这里调用了isshow属性
                        </div>
                        
                        // 全局组件cpn的组件模板
                        <template id="mycpn">
                            <div>
                                这是组件1
                            </div>
                        </template>

                        <script>
                            // 2. 全局组件cpn
                            Vue.component("cpn", {
                                template: "#mycpn",
                                data(){
                                    return {
                                        isshow: false,
                                        d2: 20
                                    }
                                }
                            });

                            // 3. vue实例
                            new Vue({
                                el: "#app",
                                data:{
                                    isshow: true,
                                    age:20
                                }
                            })
                        </script>
                    </body>
View Code

  【分析】

                        1. 在本案例中,页面元素中调用了全局组件cpn,并使用了isshow这个属性

                        2. 但在本案例中,vue实例以及全局组件中军有isshow属性

                        3. 由于html页面中的元素写在#app中,也就是说在写在vue实例里面

                        4. 因此,该html中调用的属性值为vue实例中的isshow值

    【笔者理解,不知是否正确】在定义组件中,vue实例才是一个根组件,全局组件为vue实例的最近子组件

[F] 作用域插槽

  作用域插槽的作用是实现:父组件替换插槽的标签,但是内容由子组件来提供

                    步骤:

                        1. 在子组件的模板中设置插槽,并通过v-bind将需要传递的数据绑定在自定义的变量中,这个自定义的变量的值即为我们需要的子组件的数据

                            如:

                                <template id="mycpn">

                                    <div>

                                        这是子组件

                                        <slot :data="languages"></slot>

                                    </div>

                                </template>

                        2. 在html页面中调用vue实例中的子组件时,标签内添加slot-scope="slot",

                            在内部通过slot.自定义的变量,即可访问子组件穿过案例的内容

                            实例:

                                <div id="app">

                                    <cpn>

                                        <div slot-scope="slot">

                                            <span v-for="item in slot.data">{{item}}*</span>

                                        </div>

                                    </cpn>

                                </div>

  【完整案例代码】

                    <body>
                        // html页面元素
                        <div id="app">
                            <cpn>
                                // 2.在页面中引用vue实例的子组件,在插槽中插入的内容中加入行内属性slot-scope="slot"
                                //   此后,在内部可以通过slot.data中访问子组件的languages的数据了
                                <div slot-scope="slot">
                                    <span v-for="item in slot.data">{{item}}*</span>
                                </div>
                            </cpn>
                        </div>
                    
                        // 子组件的模板内容
                        <template id="mycpn">
                            <div>
                                这是子组件
                                <slot :data="languages"></slot>
                                    // 1. 在子组件模板定义的插槽中将languages数据传过来,保存在data中
                            </div>
                        </template>
                    
                        <script>
                            // vue实例
                            new Vue({
                                el: "#app",
                                data:{
                                    isshow: true,
                                    age:20
                                },
                                components:{
                                    cpn: {
                                        template:"#mycpn",
                                        data(){
                                            return {
                                                languages:["C++", "Python", "Go", "JavaScript", "JAVA", "C#"]
                                            }
                                        },
                                    },
                                }
                            })
                        </script>
                    </body>
View Code
原文地址:https://www.cnblogs.com/carreyBlog/p/14062419.html