zoukankan      html  css  js  c++  java
  • 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

    三、混合和插槽

    1、混合

    1. 当两个组件复用共用的代码块时
    2. 定义公共的代码块
    3. 复用语法:mixins: [变量名]

    4. demo

    <body>
    <div id="app">
        <com1></com1>
        <com2></com2>
    </div>
    
    <script>
        // 定义公用代码
        let base = {
            data() {
                return {
                    is_show: false
                }
            },
            methods: {
                show_text: function(){
                    this.is_show = true;
                },
                hide_text(){
                    this.is_show = false;
                }
            }
        };
    
        let com1 = {
            template: `<div>
                            <button @click="show_text">点击显示文本</button>
                            <button @click="hide_text">点击隐藏文本</button>
                            <div v-show="is_show">威猛的明哥出现了</div>
                            </div>`,
            // 继承公用代码
            mixins: [base],
            // 还可以修改继承过来的代码
            data(){
                return {
                    is_show: true
                }
            }
        };
        
        let com2 = {
            template: `<div>
                            <button v-on="{mouseenter: show_text, mouseleave: hide_text}">鼠标移入显示文本,移出隐藏</button>
                            <div v-show="is_show">威猛的明哥出现了</div>
                            </div>`,
            // 继承代码
            mixins: [base]
        };
        
        const app = new Vue({
            el: "#app",
            components: {
                com1: com1,
                com2: com2,
            }
        })
    </script>
    </body>
    View Code

    2、 插槽

    1. 把组件的template定义在html里面
    2. 在script中通过id找到这段template
    3. template代码内定义slot插槽,并使用name属性区分不同的插槽信息
    4. 使用组件的时候通过slot,可以给组件添加上不同的内容
    5. 生成的组件代码中不会有template标签

    6. demo

    <body>
    <div id="app">
        <com>
            <h3 slot="title">Python</h3>
            <p slot="brief">从入门到精通</p>
        </com>
        <com>
            <h3 slot="title">Mysql</h3>
            <p slot="brief">从删库到跑路</p>
        </com>
    </div>
    <!--组件的template还可以单独写出来-->
    <template id="my_com">
        <div>
            <h1>这是一个组件</h1>
            <!--用slot定义插槽-->
            <slot name="title"></slot>
            <slot name="brief"></slot>
            <hr>
        </div>
    </template>
    
    <script>
        let com = {
            // 找到template模板
            template: "#my_com"
        };
        const app = new Vue({
            el: "#app",
            components: {
                com: com
            }
        })
    </script>
    </body>
    View Code
  • 相关阅读:
    Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
    Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    第一届云原生应用大赛火热报名中! helm install “一键安装”应用触手可及!
    云原生时代,2个方案轻松加速百万级镜像
    Knative 基本功能深入剖析:Knative Serving 自动扩缩容 Autoscaler
  • 原文地址:https://www.cnblogs.com/yidashi110/p/10091828.html
Copyright © 2011-2022 走看看