前端系列课程之Vue组件(一)

组件

目标:

  • 掌握Vue组件的定义
  • 掌握动态组件和父子组件的应用
  • 掌握组件间的通信方式

组件概述:

  • 组件是什么?

    Vue组件是Vue.js最强大的功能之一,用于扩展HTML元素封装可重用的代码

  • 组件的创建

  1. 通过构造器创建组件

在这里插入图片描述

  1. 直接创建(常用

在这里插入图片描述

  1. 组件命名必须全部使用小写

例子:

在这里插入图片描述

  • 组件的类型
  1. 全局组件
    (1)在Vue实例外部创建
    (2)可以在任意Vue实例挂载的DOM元素中使用

例子:

在这里插入图片描述

  1. 局部组件
    (1)在Vue实例内部,通过components选项创建
    (2)自能在创建组件的实例所挂载的DOM标签中使用

在这里插入图片描述
例子:

在这里插入图片描述


  • 组件的内部构成
  1. 组件内部包含项
    (1)模板:template
    (2)数据:data
    (必须通过函数的方式定义)

在这里插入图片描述
例子:

在这里插入图片描述

其他写法:(上面的可以写成独立的)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>组建的结构</title>
</head>

<body>
    <div id="app">
        <mycomp></mycomp>
    </div>
    <script>
        //独立
        let mycomp = {
            //多个组件必须有一个大的盒子包裹
            template: `<div>
                    <h1>{{title}}</h1>
                    <button @click="showMsg">更改</button>
                    </div>`,
            data() {
                return {
                    title: '组件的标题',
                    message: '组件的信息描述'
                }
            },
            methods: {
                showMsg() {
                    this.title = this.message
                }}
        }
        var app = new Vue({
            el: '#app',
            data: {
                title: '实例对象的标题'
            },
            components: {
                'mycomp': mycomp
            },
            data: {},
            methods: {},
        })
    </script>
</body>

</html>


(3)方法:methods
(4)…

  • 引用模板
  1. 通过template标签在页面中定义组件的内部结构
  2. 在组件内部的template选项中通过模板标签的id引用
  3. 模板要求只能有一个根元素

在这里插入图片描述
在这里插入图片描述
例子:

在这里插入图片描述


Vue组件小结:

  1. 组件作用:自定义标签

  2. 语法:
    (1)组件名(小写
    (2)组件对象:
    a. template => 引用模板id => <template></template>
    b. data => 函数方式定义
    其他…

             components:{ 组件名:组件对象 => 单独定义 }
    
  3. 实例DOM里面使用组件<组件名></组件名>
    A. <template>
    B.组件对象
    C.components
    D.<组件名><组件名>

高级组件

  • 动态组件
  1. 通过component标签实现动态改变的组件

在这里插入图片描述
例子:



<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>组建的结构</title>
</head>
<style>
    header {
        width: 100%;
        height: 100px;
        background-color: blue;
    }
    
    main {
        width: 100%;
        height: 400px;
        background-color: rgb(24, 214, 56);
    }
</style>

<body>
    <template id="mycomp">
        <!-- 必须有容器div -->
        <div>
            <header><h1>{{title}}</h1></header>
            
        </div>
    </template>
    <template id="mycomp01">
        <!-- 必须有容器div -->
        <div>
            <main> <p>{{title}}</p></main>
        </div>
    </template>

    <div id="app">
        <component :is="compName"></component>
        <button @click="compName='mycomps'">切换</button>
    </div>
    <script>
        let mycomp = {
            template: '#mycomp',
            data() {
                return {
                    title: '组件的标题',
                }
            },
        }
        let mycomp01 = {
            template: '#mycomp01',
            data() {
                return {
                    title: '组件的标题01',
                }
            },
        }
        var app = new Vue({
            el: '#app',
            data: {

            },
            components: {
                'mycomp': mycomp,
                'mycomps': mycomp01,
            },
            data: {
                compName: 'mycomp'
            },
        })
    </script>
</body>

</html>

运行结果:


在这里插入图片描述

  1. keep-alive标签可以保存动态加载组件第一次的状态

例子:(添加随机数random() )

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>组建的结构</title>
</head>
<style>
    header {
        width: 100%;
        height: 100px;
        background-color: blue;
    }
    
    main {
        width: 100%;
        height: 100px;
        background-color: rgb(24, 214, 56);
    }
</style>

<body>
    <template id="mycomp">
        <!-- 必须有容器div -->
        <div>
            <header><h1>{{title}}</h1>
            <p>{{num}}</p></header>
            
        </div>
    </template>
    <template id="mycomp01">
        <!-- 必须有容器div -->
        <div>
            <main> <p>{{title}}</p>
                <p>{{num}}</p></main>
        </div>
    </template>

    <div id="app">
        <component :is="compName"></component>
        <button @click="compName='mycomps'">切换到下一页</button>
        <button @click="compName='mycomp'">返回上一页</button>
    </div>
    <script>
        let mycomp = {
            template: '#mycomp',
            data() {
                return {
                    title: '组件的标题',
                    num: Math.random()
                }
            },
        }
        let mycomp01 = {
            template: '#mycomp01',
            data() {
                return {
                    title: '组件的标题01',
                    num: Math.random()
                }
            },
        }
        var app = new Vue({
            el: '#app',
            data: {

            },
            components: {
                'mycomp': mycomp,
                'mycomps': mycomp01,
            },
            data: {
                compName: 'mycomp'
            },
        })
    </script>
</body>

</html>

运行结果:

每次切换后 ,随机数都不相同
在这里插入图片描述
在这里插入图片描述

解决方法:


在这里插入图片描述


练习:

  使用动态组件实现以下Tab选项切换效果:

在这里插入图片描述

  • 父子组件
  1. 父子组件是存在嵌套关系的组件

例子:

在这里插入图片描述

  1. 组件定义时的嵌套
    在这里插入图片描述

  2. 组件使用时的嵌套
    在这里插入图片描述

例子:(父子组件的定义)

在这里插入图片描述


运行结果:

在这里插入图片描述
代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>父子组件的定义</title>
</head>

<body>
    <!-- A.创建子组件模板 -->
    <template id="son">
        <div>
            <h2>{{title}}</h2>
        </div>
        </template>
    <!--1. 定义父组件模板 -->
    <template id="father">
        <div>
            <h1>{{title}}</h1>
             <!-- D.使用父组件 -->
            <mysons></mysons>
        </div>
    </template>
    <div id="app">
        <!-- 4.使用父组件 -->
        <myfathers></myfathers>
    </div>
    <script>
        // B.创建子组件对象
        let sons = {
                template: '#son',
                data() {
                    return {
                        title: '子组件的标题'
                    }
                }
            }
            // 2.创建父组件对象
        let fathers = {
            template: '#father',
            data() {
                return {
                    title: '父组件的标题'
                }
            },
            // C.定义子组件
            components: {
                'mysons': sons
            }
        }
        var app = new Vue({
            el: '#app',
            data: {},
            // 3.定义父组件
            components: {
                'myfathers': fathers,
            }
        })
    </script>
</body>

</html>


  • 子组件获取父组件的数据
  1. 在子组件中通过props选项定义属性
    在这里插入图片描述

  2. 在父组件中,把父组件的数据和子组件的属性进行绑定
    在这里插入图片描述

  3. 子组件模板中使用父组件数据

例子:

在这里插入图片描述

运行结果:

在这里插入图片描述

代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>父组件传参到子组件</title>
</head>

<body>
    <!-- A.创建子组件模板 -->
    <template id="son">
        <div>
            <h2>{{title}}</h2>
            <!-- (3).使用父组件数据 -->
            <div style="width: 100; height: 100px; border: 1px solid red;">
                {{son_message}}</div>
        </div>
        </template>
    <!--1. 定义父组件模板 -->
    <template id="father">
        <div>
            <h1>{{title}}</h1>
             <!-- D.使用父组件 -->
             <!-- (2).绑定数据 -->
            <mysons :son_message="message"></mysons>
        </div>
    </template>
    <div id="app">
        <!-- 4.使用父组件 -->
        <myfathers></myfathers>
    </div>
    <script>
        // B.创建子组件对象
        let sons = {
                template: '#son',
                data() {
                    return {
                        title: '子组件的标题'
                    }
                },
                // (1).定义子组件接收参数的属性名
                props: ['son_message']
            }
            // 2.创建父组件对象son_message
        let fathers = {
            template: '#father',
            data() {
                return {
                    title: '父组件的标题',
                    message: '这是父组件的内容!'
                }            },
            // C.定义子组件
            components: {
                'mysons': sons
            }        }
        var app = new Vue({
            el: '#app',
            data: {},
            // 3.定义父组件
            components: {
                'myfathers': fathers,
            }
        })
    </script>
</body>

</html>




  • 父组件获取子组件数据
  1. 子组件把数据通过事件方式发送出去,事件名必须小写
    在这里插入图片描述

  2. 父组件中,注册子组件的事件,并添加事件处理方法
    在这里插入图片描述

  3. 在事件处理方法中获取子组件的数据
    在这里插入图片描述
    例子:

在这里插入图片描述

运行结果:

在这里插入图片描述

代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>子组件传参到父组件</title>
</head>

<body>
    <!-- A.创建子组件模板 -->
    <template id="son">
        <div>
            <h2>{{title}}</h2>
            <button @click="sendMsg">发送数据</button>
        </div>
        </template>
    <!--1. 定义父组件模板 -->
    <template id="father">
        <div>
            <h1>{{title}}</h1>
             <!-- D.使用父组件 -->
             <!-- 二.注册子组件的事情,并确定后续处理方法 -->
            <mysons @e_send='reserve'></mysons>
            
        </div>
    </template>
    <div id="app">
        <!-- 4.使用父组件 -->
        <myfathers></myfathers>
    </div>
    <script>
        // B.创建子组件对象
        let sons = {
                template: '#son',
                data() {
                    return {
                        title: '子组件的标题',
                        message: '这是子组件定义的内容'
                    }
                },
                methods: {
                    // 一.通过事件方式发送数据
                    sendMsg() {
                        this.$emit('e_send', this.message)
                    }
                }
            }
            // 2.创建父组件对象
        let fathers = {
            template: '#father',
            data() {
                return {
                    title: '父组件的标题'
                }
            },
            // 三.获取参数
            methods: {
                reserve(result) {
                    console.log('result:' + result)
                }

            },
            // C.定义子组件
            components: {
                'mysons': sons
            },
        }
        var app = new Vue({
            el: '#app',
            data: {},
            // 3.定义父组件
            components: {
                'myfathers': fathers,
            }
        })
    </script>
</body>

</html>


  • 单向数据流
  1. 父组件的数据变化时,会影响到子组件数据

例子:(单向数据流)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>单向数据流</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.8/vue.js"></script>
</head>
<script>
    // A.定义子组件
    let son = {
            template: '#son',
            data() {
                return {
                    title: '子组件'
                }
            },
            //一、定义子组件的接收参数的属性名
            props: ['son_message']
        }
        //2.创建父组件对象
    let father = {
        template: '#father',
        data() {
            return {
                title: '父组件',
                message: '这是父组件的内容!'
            }
        },
        //C.子组件的定义
        components: {
            'son': son
        }
    }

    window.onload = function() {
        let vm = new Vue({
            el: '#mydiv',
            data: {},
            //3.定义父组件
            components: {
                'father': father,
            }



        })
    }
</script>

<body>
    <template id="son">
        <div>
            <h1>{{title}}</h1>
            
            <div style="width: 200px;height: 100px;border: 2px solid #cccccc;">
            {{son_message}}
            </div>
        </div>
    </template>
    <!-- 1.定义父组件模板 -->
    <template id="father">
        <div>
            <h1>{{title}}</h1>
            <!-- D.使用子组件 -->
            <!-- 二、父组件的属性绑定 -->
            <son :son_message='message'></son>
        <button @click="message='This is father centent'">修改数据</button>
        </div>
    </template>
    <div id="mydiv">
        <!-- 4.使用父组件 -->
        <father></father>
    </div>
</body>

</html>

运行结果:

在这里插入图片描述


2. 绑定的子组件数据变化时,不会影响到父组件的数据,且不能直接修改父组件的数据


例子:(单向数据流的反操作)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>单项数据流_反操作</title>
    <script>
        //B.创建父组件对象
        let son = {
                template: '#son',
                data() {
                    return {
                        title: '子组件的标题',
                        message: '这是子组件内部的数据'
                    }
                },
                methods: {
                    // 一、通过事件方式发送数据
                    sendMsg() {
                        this.$emit('e_send', this.message)
                    },
                    editMsg() {
                        this.message = "this is son messges"
                    }
                }
            }
            //2.创建父组件对象
        let father = {
            template: '#father',
            data() {
                return {
                    title: '父组件的标题',
                    info: ''
                }
            },
            methods: {
                // 三、使用子组件传入数据
                receive(result) {
                    // console.log('result', result)
                    this.info = result
                }
            },
            // C.子组件的定义
            components: {
                'son': son
            }
        }
        window.onload = function() {
            let vm1 = new Vue({
                el: '#mydiv',
                data: {},
                //3.定义父组件
                components: {
                    'father': father,
                }
            })
        }
    </script>
</head>

<body>
    <!-- A.定义子组件模板 -->
    <template id="son">
        <div>
            <h1>{{title}}</h1>
            <button @click="sendMsg">发送数据</button>
            <button @click="editMsg">修改数据</button>
        </div>
    </template>
    <!-- 1.定义父组件模板 -->
    <template id="father">
        <div>
            <!-- 子组件传入数据 -->
            <h1>{{title}}</h1>
            <p>子组件传入数据:{{info}}</p>
            <!-- D.使用子组件 -->
            <!-- 二、注册子组件的事件,并确定后续处理 -->
            <son @e_send='receive'></son>
        </div>
    </template>
    <div id="mydiv">
        <!-- 4.使用父组件 -->
        <father></father>
    </div>

</body>

</html>

运行结果:

在这里插入图片描述


  • 单向数据流的解决方案
  1. 使用事件触发和sync修饰符实现修改父元素的数据

例子:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>解决单向数据流方案(使用事件触发)</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.8/vue.js"></script>
</head>
<script>
    // A.定义子组件
    let son = {
            template: '#son',
            data() {
                return {
                    title: '子组件'
                }
            },
            //一、定义子组件的接收参数的属性名
            props: ['son_message'],
            methods: {
                editData() {
                    // this.son_message = 'hello'
                    //不能直接修改绑定父组件传入的数据
                    //*******解决单项数据流第一步
                    this.$emit('e_edit', 'hello')
                }
            },
        }
        //2.创建父组件对象
    let father = {
        template: '#father',
        data() {
            return {
                title: '父组件',
                message: '这是父组件的内容!'
            }
        },
        //C.子组件的定义
        components: {
            'son': son
        },
        methods: {

            modify(result) {
                this.message = result
            }
        }
    }
    window.onload = function() {
        let vm = new Vue({
            el: '#mydiv',
            data: {},
            //3.定义父组件
            components: {
                'father': father,
            }



        })
    }
</script>

<body>
    <template id="son">
        <div>
            <h1>{{title}}</h1>
            
            <div style="width: 200px;height: 100px;border: 2px solid #cccccc;">
            {{son_message}}
            </div>
            <button @click ='editData'>修改父元素数据</button>
        </div>
    </template>
    <!-- 1.定义父组件模板 -->
    <template id="father">
        <div>
            <h1>{{title}}</h1>
            <p>{{message}}</p>
            <!-- D.使用子组件 -->
            <!-- 二、父组件的属性绑定 -->
            <son :son_message='message' @e_edit='modify'></son>
        <button @click="message='这是父组件的新内容This is father centent'">修改数据</button>
        </div>
    </template>
    <div id="mydiv">
        <!-- 4.使用父组件 -->
        <father></father>
    </div>
</body>

</html>

显示结果:

在这里插入图片描述


  1. 使用面向对象的特性实现修改父元素的数据

例子:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>解决单向数据流--面向对象方式</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.8/vue.js"></script>
</head>
<script>
    // A.定义子组件
    let son = {
            template: '#son',
            data() {
                return {
                    title: '子组件'
                }
            },
            //一、定义子组件的接收参数的属性名
            props: ['son_message'],
            methods: {
                edit() {
                    this.son_message.content = 'hello'
                }
            }
        }
        //2.创建父组件对象
    let father = {
        template: '#father',
        data() {
            return {
                title: '父组件',
                // message: '这是父组件的内容!',
                message: {
                    content: '这是父组件内容'
                }
            }
        },
        //C.子组件的定义
        components: {
            'son': son
        }
    }

    window.onload = function() {
        let vm = new Vue({
            el: '#mydiv',
            data: {},
            //3.定义父组件
            components: {
                'father': father,
            }



        })
    }
</script>

<body>
    <template id="son">
        <div>
            <h1>{{title}}</h1>
            
            <div style="width: 200px;height: 100px;border: 2px solid #cccccc;">{{son_message.content}}</div>
            <button @click='edit'>修改父元素数据</button>
        </div>
    </template>
    <!-- 1.定义父组件模板 -->
    <template id="father">
        <div>
            <h1>{{title}}</h1>
            <p>{{message.content}}</p>
            <!-- D.使用子组件 -->
            <!-- 二、父组件的属性绑定 -->
            <son :son_message='message'></son>
        <button @click="message.content='这是父组件的新内容This is father centent'">修改数据</button>
        </div>
    </template>
    <div id="mydiv">
        <!-- 4.使用父组件 -->
        <father></father>
    </div>
</body>

</html>

运行结果:
在这里插入图片描述

练习:

  1. 创建一个商品数据展示组件,其中包含一个搜索子组件(包含一个文本框和一个按钮),要求在搜索子组件中完成数据搜索功能,然后在商品展示组件中显示搜索到的数据,默认显示全部数据
  2. 搜索子组件:接受输入查询关键字,查询数据
  3. 展示组件:显示数据

例子:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>商品搜索</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.8/vue.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    <script>
        window.onload = function() {
            let search = {
                template: '#search',
                data() {
                    return {
                        searchKey: '',
                        datas: []
                    }
                },
                mounted() {
                    $.getJSON('productsAll.json', (result) => {
                        this.datas = result.data
                            //把子组件的数据发送
                        this.$emit('e_getdatas', this.datas)
                    })
                },
                methods: {
                    query() {
                        let queryData = []
                        for (let i = 0; i < this.datas.length; i++) {
                            if (this.datas[i].brand == this.searchKey) {
                                queryData.push(this.datas[i])
                            }

                        }
                        this.$emit('e_getdatas', queryData)
                    }
                }

            }
            let productlist = {
                template: '#productList',
                data() {
                    return {
                        products: []
                    }
                },
                components: {
                    'search': search
                },
                methods: {
                    receice(datas) {
                        this.products = datas
                    }
                }
            }
            let vm1 = new Vue({
                el: '#mydiv',
                data: {},
                components: {
                    'productlist': productlist
                }
            })

        }
    </script>
</head>

<body>
    <template id="search">
        <div>
            <input type="text" name="" id="" v-model='searchKey'>
            <button @click="query">搜索</button>
        </div>
    </template>
    <template id="productList">
        <div>
            <search @e_getdatas='receice'></search>
                <table>
            <tr>
                <th>商品图片</th>
                <th>商品描述</th>
                <th>品牌</th>
                <th>价格</th>
            </tr>
            <tr v-for ='product in products'>
               <td><img :src='product.imgPath' alt=""></td>
               <td>{{product.title}}</td>
               <td>{{product.brand}}</td>
               <td>{{product.price}}</td>
            </tr>
        </table> 
        </div>
        <!-- 搜索子组件 -->
   
    </template>
    <div id="mydiv">
        <productlist></productlist>
    </div>

</body>

</html>


  • 非父子组件间的通信
  1. 通过空的Vue实例对象创建中央事件的总线,实现事件的监听和触发,完成数据的传输。
  2. 事件总线对象的创建必须在Vue实例之前完成

例子:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动态组件</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.8/vue.js"></script>
    <script>
        window.onload = function() {
            //创建中央事件总线
            let eventBus = new Vue({

            })
            let header = {
                template: '#header',
                data() {
                    return {
                        title: '组件的标题页头',
                        userName: 'tom'
                    }
                },
                methods: {
                    send() {
                        // 兄弟组件发送数据
                        eventBus.$emit('e_send', this.userName)
                    }
                }
            }
            let main = {
                template: '#main',
                data() {
                    return {
                        title: '组件的标题内容',
                        num: Math.random()
                    }
                },
                // 被挂载就开始监听
                mounted() {
                    eventBus.$on('e_send', (val) => {
                        alert(val)
                    })
                }
            }

            let vm1 = new Vue({
                el: '#mydiv',
                data: {
                    title: '实例对象的标题',
                    compName: 'myheader'
                },
                components: {

                    'myheader': header,
                    'mymain': main,

                },
                methods: {},
            })
        }
    </script>
</head>

<body>
    <template id="header">
        <div>
            <div style="width: 1190px;height: 100px;margin: 0 auto;background-color: cadetblue;">
<h1>xxx网站页头</h1>
<span>欢迎你{{userName}}</span>
            </div>
            <button @click="send">传参</button>
        </div>
    </template>
    <template id="main">
        <div>
            <div style="width: 1190px;height: 400px;margin: 0 auto;background-color: rgb(13, 125, 129);">
<h1>xxx网站内容</h1>
<p>{{num}}</p>
            </div>
        </div>
    </template>
    <div id="mydiv">
        <myheader></myheader>
        <mymain></mymain>
    </div>
</body>

</html>


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
-Vue组件slot

  1. 父子组件混合使用时,slot用于实现组件的内容分发
  2. 在子组件的内部中添加slot标签,在父组件模板中添加内容,该内容将替换slot标签。
  3. slot类型:
    (1)匿名slot
    (2)具名slot
    (3)作用域slot

例子:(匿名)


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>匿名slot</title>
    <script>
        window.onload = function() {
            let mycomp = {
                template: '#mycomp'
            }
            let vm1 = new Vue({
                el: '#mydiv',
                data: {},
                //3.定义父组件
                components: {
                    'mycomp': mycomp,
                }
            })
        }
    </script>
</head>

<body>

    <template id="mycomp">
        <div>  
             <!-- slot组件不存在时,组件模板会覆盖组件标签内部的内容 -->
            <!-- slot存在时,组件标签内部的内容会替换slot标签 -->
              <slot></slot>  
            <h1>我是组件的标题</h1>
        </div>
    </template>
    <div id="mydiv">
        <mycomp>
            <h1>父级容器提供的标题</h1>
            <hp>父级容器提供的内容</p>
        </mycomp>
    </div>

</body>

</html>

运行结果:

在这里插入图片描述


例子:(具名slot)

在这里插入图片描述





<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.0/vue.js"></script>
    <title>slot具名</title>
    <script>
        window.onload = function() {
            let mycomp = {
                template: '#mycomp'
            }
            let vm1 = new Vue({
                el: '#mydiv',
                data: {},
                //3.定义父组件
                components: {
                    'mycomp': mycomp,
                }
            })
        }
    </script>
</head>

<body>

    <template id="mycomp">
        <div>  
             <!-- slot组件不存在时,组件模板会覆盖组件标签内部的内容 -->
            <!-- slot存在时,组件标签内部的内容会替换slot标签 -->
              <slot name='header'></slot>  
            <h1>我是组件的标题</h1>
             <slot name='footer'></slot>
             <slot></slot>
        </div>
    </template>
    <div id="mydiv">
        <mycomp>
            <h1 slot="header">父级容器提供的标题</h1>
            <p slot="footer">父级容器提供的内容</p>
            <ul>
                <li>首页</li>
                <li>商品</li>
                <li>个人中心</li>
            </ul>
        </mycomp>
    </div>

</body>

</html>


  • slot类型:
  1. 匿名slot

在这里插入图片描述
在这里插入图片描述

  1. 具名slot

在这里插入图片描述
在这里插入图片描述

  1. 作用域slot
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值