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
  • 相关阅读:
    BitTorrent Sync 基于BT的文件同步
    转载:安装Ubuntu 15.10后要做的事
    VMware 虚拟机安装OSX el capitan 11.12
    GitStack 第三方开源服务器端
    一些不错的设计网站
    Spark注册UDF函数,用于DataFrame DSL or SQL
    R和Tableau平行坐标图
    Scala断言
    Spark Gradient-boosted trees (GBTs)梯度提升树
    Spark Multilayer perceptron classifier (MLPC)多层感知器分类器
  • 原文地址:https://www.cnblogs.com/yidashi110/p/10091828.html
Copyright © 2011-2022 走看看