Vue组件以及组件之间的通信

一、组件的注册

1、 全局组件注册

1. 注册基本语法Vue.component

复制代码
    Vue.component("my_header", {
        template: `<div><h1>{{title}}</h1></div>`,
        data() {
            return {
                title: "这是头部"
            }
        }
    });
View Code
复制代码

2. 第一个参数"my_header":组件名称
3. 第二个参数{}:配置信息
4. 配置信息里面必须要有template,它的值是这个组件的html代码
5. 还可以有data、methods等参数,不同的是data不是对象了,而是函数,return返回的值,在template中可以获取并使用
函数详写是 data:function(){}; ES6中可以直接简写 data(){return },其他函数一样可以简写省略 :function
6. Vue里面有的参数,组件里面多数也有,但是有一些参数是组件不能有的,比如el参数,所有组件都是Vue可复用的实例
7. 全局组件,所有app都可以使用

8. demo

复制代码
<body>
<div id="app">
    <my_header></my_header>
</div>

<hr>

<div id="app2">
    <my_header></my_header>
</div>

<script>
    Vue.component("my_header", {
        template: `<div><h1>{{title}}</h1></div>`,
        data() {
            return {
                title: "这是头部"
            }
        }
    });
    const app = new Vue({
        el: "#app",
        
    });
    
    const app2 = new Vue({
        el: "#app2"
    })
</script>
</body>
View Code
复制代码

 

2、局部组件注册

1. 在某个app下注册组件,其他app不能使用
2. 基本语句:某个app内使用参数components: {组件名称1: 配置信息1, 组件名称2: 配置信息2}

3. demo

复制代码
<body>
<div id="app">
    <my_com></my_com>
    <my_com></my_com>
</div>

<script>
    // 组件配置信息(对象)
    let my_com_config = {
        template: `<div><h1>这是局部组件</h1></div>`
    };
    const app = new Vue({
        el: "#app",
        components: {
            // 组件名称: 配置信息
            my_com: my_com_config
        }
        
    });
</script>
</body>
View Code
复制代码

 

3、子组件的注册

1. 在某个组件内,也可以使用components注册它的子组件
2. 子组件需要这个组件的template代码内使用

3. demo

复制代码
<body>
<div id="app">
    <my_com></my_com>
</div>
<script>
    let child_config = {
        template: `<div><h2>我是子组件</h2></div>`
    };
    let my_com_config = {
        // 在组件的代码里面引用它的子组件
        template: `<div>
                    <h1>这是一个组件</h1>
                    <child></child>
                    </div>`,
        // 在某个组件内部也可以定义的它的子组件
        components: {
            child: child_config
        }
    };
    const app = new Vue({
        el: "#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
View Code
复制代码

 

二、组件之间的通信

1、父子组件之间的通信

1. 在父组件的配置信息template中引用子组件,给子组件设置一个属性,值是父组件data的值
2. 在子组件中配置一个props参数(数组),里面是那个属性名
3. 然后在子组件的template代码中就可以直接使用这个属性获取到父组件传过来的值

4. demo

复制代码
<body>
<div id="app">
    <my_com></my_com>
</div>

<script>
    let child_config = {
        template: `<div>
                    <h2>我是子组件</h2>
                    <p>父亲对我说:{{father_say}}</p>
                    </div>`,
        props: ["father_say"]
    };
    let my_com_config = {
        template: `<div>
                    <h1>这是一个组件</h1>
                    <child :father_say="f_say"></child>
                    </div>`,
        components: {
            child: child_config
        },
        data(){
            return {
                f_say: "好好学习"
            }
        }
    };
    const app = new Vue({
        el: "#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
View Code
复制代码

 

2、子父组件之间的通信

1. 子组件向父组件传数据,需要提交一个事件
2. 通过this.$emit("事件名称", "要传的值")提交一个事件给父亲
3. 在父组件中绑定子组件提交过来的事件,创建一个方法处理这个事件
4. data函数接收子组件提交过来的数据

5. demo

复制代码
<body>
<div id="app">
    <my_com></my_com>
</div>
<script>
    let child_config = {
        // 设置一个click事件,通过click事件向父亲提交一个事件son_say和数据
        template: `<div>
                    <h2>我是一个子组件</h2>
                    <button @click="my_click">点击向父亲说话</button>
                    </div>`,
        methods: {
            my_click() {
                // 向父亲说话
                // 子组件提交事件
                this.$emit("son_say", "我会好好学习的")
            }
        }
    };
    let my_com_config = {
        // 父组件接收子组件提交的事件son_say,并给这个事件设置一个处理方法my_son_say
        // 处理后的数据就可以使用了{{say}}
        template: `<div>
                    <h1>这是一个组件</h1>
                    <child @son_say="my_son_say"></child>
                    <p>儿子跟我说:{{say}}</p>
                    </div>
                    `,
        components:{
            child: child_config
        },
        data(){
           return {
               say: ""
           }
        },
        // 接收子组件传来的数据data,并赋值给say,在代码中展示出来
        methods: {
            my_son_say: function (data) {
                this.say = data
            }
        }
    };
    const app = new Vue({
        el: "#app",
        components: {
            my_com: my_com_config
        }
    })
</script>
</body>
View Code
复制代码

 

3、非父子组件之间的通信

1. 定义一个Vue实例作为两个组件之间通信的桥梁
2. 其中一个组件向中间调度器提交事件:Event.$emit("事件名称", data)
3. 另一个组件要监听中间调度器里的事件:Event.$on("事件的名称", function(data)
4. 注意this的问题:函数里面的this是最近的调用者,外面的this才是这个组件

5. demo

复制代码
<body>
<div id="app">
    <ming></ming>
    <hong></hong>
</div>

<script>
    // 这个Vue实例不用传数据,只是用于两个组件之间通信的桥梁
    // 一个组件给这个实例提交事件,另一个组件在这个实例里监听这个事件
    let other = new Vue();

    let ming_config = {
        template: `<div>
                          <h1>我是明哥</h1>
                          <button @click="my_click">给小红打电话</button>
                          </div>`,
        methods: {
            my_click: function() {
                // 给小红打电话,说晚上等我,一起嗨
                // 两个组件之间没有关系(不是父子),需要通过一个Vue对象进行通信
                // 给other对象提交事件
                other.$emit("call", "晚上等我,一起嗨")
            }
        }
    };
    let hong_config = {
        template: `<div>
                            <h1>我是红姐</h1>
                            <p>明哥勇猛地跟涐说:{{ming_say}}</p>
                            </div>`,
        data(){
            return {
                ming_say: ""
            }
        },
                            
        // 钩子方法,组件加载完成后会执行这个方法
        mounted(){
            // 和$emit是一对的,$emit是提交事件,$on是监听$emit提交的事件
            // 第一个参数是监听的事件名称,第二个参数是监听到后要执行的回调函数
            let that = this;  // 这个this是hong这个组件
            other.$on("call", function(data){
                // data是ming传过来的数据,里面的this是other的
                that.ming_say = data;
            })
        }
    };

    const app = new Vue({
        el: "#app",
        components: {
            ming: ming_config,
            hong: hong_config
        }
    })
</script>
</body>
View Code
复制代码

 

4、总结

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head>

<body>
<div id="app">
    <my_com></my_com>
    <ming></ming>
    <hong></hong>
</div>

<script>
    let other = new Vue();
    let child_config = {
        template: `<div><p>子组件{{father_say}}</p>
                    <button @click="my_click">向父组件通信</button></div>
`,
        props: ["father_say"],
        methods: {
            my_click: function () {
                this.$emit("son_say", "I will")
            }
        }
    };
    let my_com_config = {
        template: `<div>
                    <h1>父组件</h1>
                    <child :father_say="f_say" @son_say="s_say"></child>
                     <p>儿子跟我说:{{s_data}}</p>
                    </div>`,
        components: {
            child: child_config
        },
        data() {
            return {
                f_say: "好好学习",
                s_data: ""
            }
        },
        methods: {
            s_say(data) {
                this.s_data = data
            }
        }
    };

    let ming_config = {
        template: `
                  <div>
                    <p>我是明哥</p>
                    <button @click="my_click">给小红打电话</button>
                  </div>
        `,
        methods: {
            my_click() {
                other.$emit("call", "晚上一起嗨嗨嗨")
            }
        }
    };
    let hong_config = {
        template: `<div>
                    <h1>我是红姐</h1>
                    <p>明哥勇猛地跟涐说:{{ming_say}}</p>
                   </div>`,
        data() {
            return {
                "ming_say": ""
            }
        },
        mounted() {
            that = this;
            other.$on("call", function (data) {
                that.ming_say = data
            })
        }
    };

    const app = new Vue({
        el: "#app",
        components: {
            my_com: my_com_config,
            ming: ming_config,
            hong: hong_config,
        }
    });
</script>
</body>

</html>
View Code
复制代码

 

5、拓展

不同vue实例的组件,通信方法跟非父子方法一致

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Title</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
</head>

<body>
<div id="app"> <!--vue实例1-->
    <ming></ming>
</div>
<div id="app2"> <!--vue实例2-->
    <hong></hong>
</div>
<script>
    // 用于组件通信的vue实例
    let other = new Vue();

    let ming_config = {
        template: `
                  <div>
                    <p>我是明哥</p>
                    <button @click="my_click">给小红打电话</button>
                  </div>
        `,
        methods: {
            my_click() {
                other.$emit("call", "晚上一起嗨嗨嗨")
            }
        }
    };
    let hong_config = {
        template: `<div>
                    <h1>我是红姐</h1>
                    <p>明哥勇猛地跟涐说:{{ming_say}}</p>
                   </div>`,
        data() {
            return {
                "ming_say": ""
            }
        },
        mounted() {
            that = this;
            other.$on("call", function (data) {
                that.ming_say = data
            })
        }
    };

    // vue实例1
    const app = new Vue({
        el: "#app",
        components: {
            ming: ming_config,
        }
    });

    // vue实例2
    const app2 = new Vue({
        el: "#app2",
        components: {
            hong: hong_config,
        }
    })
</script>
</body>

</html>
View Code
复制代码

 

posted @   我用python写Bug  阅读(362)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示