深入讲解Vue中父子组件通信与事件触发


Posted in Vue.js onMarch 22, 2022

一、组件

子组件

<template>
  <div style="border:1px solid black;width:400px; height: 130px;">
    <h3>我是子组件</h3>
    <button>子组件将值传递给父组件</button>
    <div>子组件接收父组件的值:</div>
  </div>
</template>

父组件

<template>
 <div style="border:1px solid red;padding:2rem;width:400px;margin:0 auto;">
    <h3>我是父组件</h3>
    <div>子组件向父组件传递的值:</div>
    <Child></Child>
  </div>
</template>

<script>
import Child from './Child';
export default {
    components: {
        Child
    }
}
</script>

效果展示:

深入讲解Vue中父子组件通信与事件触发

通过这张图可以看出父子组件的结构,下面我们来实习父子组件通信。

二、父子组件通信

父组件给子组件通信

实现思路:子组件通过 props 来接受父组件传过来的值。

  • 在父组件中,定义一个data变量,在子组件标签中动态绑定这个值。

    // Father.vue
    <template>
     <div style="border:1px solid red;padding:2rem;width:400px;margin:0 auto;">
        <h3>我是父组件</h3>
        <div>子组件向父组件传递的值:{{ChildMsg}}</div>
        <Child :FatherMsg="data"></Child>
      </div>
    </template>
    
    <script>
    import Child from './Child';
    export default {
        data() {
            return {
                data: 'I am your father',
            }
        },
        components: {
            Child
        }
    }
    </script>
  • 接着在子组件里通过 props 来接收,这样子组件就接收到了父组件传递过来的值了。

    // Child.vue
    <template>
      <div style="border:1px solid black;width:400px; height: 130px;">
        <h3>我是子组件</h3>
        <button>子组件将值传递给父组件</button>
        <div>父组件向子组件传递的值:{{FatherMsg}}</div>
      </div>
    </template> 
    
    <script>
    export default {
        data() {
            return {
                data: 'I am your children',
            }
        },
        props: ['FatherMsg']
    }
    </script>

深入讲解Vue中父子组件通信与事件触发

可以看到,我们父组件向子组件通信已经实现了,接下来就是子组件向父组件通信了,这个就要使用到 this.$emit 方法了。

子组件向父组件通信

实现思路:通过在子组件中使用 this.$emit 来触发自定义事件并传值,然后在父组件中监听该事件即可。

  • 在子组件中给 button 按钮添加 click 事件,来通过 this.$emit 自定义事件,并传入一个参数:

    <template>
      <div style="border:1px solid black;width:400px; height: 130px;">
        <h3>我是子组件</h3>
        <button @click="send">子组件将值传递给父组件</button>
        <div>父组件向子组件传递的值:{{FatherMsg}}</div>
      </div>
    </template> 
    
    <script>
    export default {
        data() {
            return {
                data: 'I am your children',
            }
        },
        props: ['FatherMsg'],
        methods: {
          send() {
            this.$emit('ListenChild', this.data);
          }
        }
    }
    </script>
  • 在父组件中的子组件标签里,先在 data 里定义一个变量接收这个值,然后监听在子组件中自定义的事件,并接受这个参数赋值给定义的变量:

    <template>
     <div style="border:1px solid red;padding:2rem;width:400px;margin:0 auto;">
        <h3>我是父组件</h3>
        <div>子组件向父组件传递的值:{{ChildMsg}}</div>
        <Child :FatherMsg="data" @ListenChild="ListenChild"></Child>
      </div>
    </template>
    
    <script>
    import Child from './Child';
    export default {
        data() {
            return {
                data: 'I am your father',
                ChildMsg: '',
            }
        },
        components: {
            Child
        },
        methods: {
            ListenChild(data) {
                console.log("子组件传递过来的值:" , data);
                this.ChildMsg = data;
            }
        }
    }
    </script>

点击子组件中的“子组件将值传递给父组件”,就可看到如下效果:

深入讲解Vue中父子组件通信与事件触发

三、父子组件事件触发

父组件调用子组件中的事件方法

  • 通过 ref 直接调用子组件的方法:

    // Child.vue 
    <template>
      <div style="border: 1px solid black; width: 150px; margin: 10px auto">
        我是子组件
        <div style="color: red"> {{ msg }} </div>
      </div>
    </template>
    <script>
    export default {
        data() {
            return {
                msg: '',
            }
        },
      methods: {
        childFun() {
          console.log('我是子组件的方法 childFun');
          this.msg = '我的方法被调用了'
        },
      },
    };
    </script>

    在子组件标签上添加 ref 属性,然后在方法中通过 this.$refs 找到绑定 ref 的属性调用该子组件内的方法即可。

    // Father.vue
    <template>
      <div style="border: 1px solid red; width: 200px; padding: 10px; margin: 0 auto">
        我是父组件
        <Button @click="handleClick">点击调用子组件方法</Button>
        <Child ref="child" />
      </div>
    </template>    
    
    <script>
    import Child from './Child';
    
    export default {
        components: {
            Child
        },
        methods: {
            handleClick() {
                this.$refs.child.childFun();
            },
        },
    }
    </script>
  • 通过组件的 $emit$on 方法:

    // Child.vue 
    <template>
      <div style="border: 1px solid black; width: 150px; margin: 10px auto">
        我是子组件
        <div style="color: red"> {{ msg }} </div>
      </div>
    </template>
    <script>
    export default {
        data() {
            return {
                msg: '',
            }
        },
      mounted() {
        this.$on('childFun', function() {
            console.log('我是子组件方法');
            this.msg = '我的方法被调用了'
        });
      }
    };
    </script>

    在子组件中使用 $on 绑定一个方法,然后在父组件中通过 $emit 找到绑定 $on 上面的事件名即可,但是也需要 ref 的配合。

    // Father.vue
    <template>
      <div style="border: 1px solid red; width: 200px; padding: 10px; margin: 0 auto">
        我是父组件
        <Button @click="handleClick">点击调用子组件方法</Button>
        <Child ref="child" />
      </div>
    </template>    
    
    <script>
    import Child from './Child';
    
    export default {
        components: {
            Child
        },
        methods: {
            handleClick() {
            	//子组件$on中的名字
                this.$refs.child.$emit("childFun")    
            },
        },
    }
    </script>

两种实现方式效果一致。

调用方法前:

深入讲解Vue中父子组件通信与事件触发

调用方法后:

深入讲解Vue中父子组件通信与事件触发

深入讲解Vue中父子组件通信与事件触发

子组件调用父组件中的事件方法

  • 直接在子组件中通过 this.$parent 来调用父组件的方法

    // Father.vue
    <template>
      <div style="border: 1px solid red; width: 200px; padding: 10px; margin: 0 auto" >
        我是父组件
        <Child></Child>
        <div style="color: red"> {{ msg }} </div>
      </div>
    </template>
    <script>
      import Child from './Child';
      export default {
          data() {
              return {
                  msg: ''
              }
          },
        components: {
          Child
        },
        methods: {
          fatherMethod() {
            console.log('我的父组件中的方法');
            this.msg = '我的方法被子组件调用了';
          }
        }
      };
    </script>
    // Child.vue
    <template>
      <div style="border: 1px solid black; width: 150px; margin: 10px auto">
        我是子组件
        <button @click="childMethod">点击调用父组件方法</button>
      </div>
    </template>
    <script>
      export default {
        methods: {
          childMethod() {
            this.$parent.fatherMethod();
          }
        }
      };
    </script>
  • 在子组件里用 $emit 向父组件触发一个事件,父组件监听这个事件(推荐使用)

    // Father.vue
    <template>
      <div style="border: 1px solid red; width: 200px; padding: 10px; margin: 0 auto" >
        我是父组件
        <Child @fatherMethod="fatherMethod"></Child>
        <div style="color: red"> {{ msg }} </div>
      </div>
    </template>
    <script>
      import Child from './Child';
      export default {
          data() {
              return {
                  msg: ''
              }
          },
        components: {
          Child
        },
        methods: {
          fatherMethod() {
            console.log('我的父组件中的方法');
            this.msg = '我的方法被子组件调用了';
          }
        }
      };
    </script>

    子组件可以使用 $emit 触发父组件的自定义事件。

    // Child.vue
    <template>
      <div style="border: 1px solid black; width: 150px; margin: 10px auto">
        我是子组件
        <button @click="childMethod">点击调用父组件方法</button>
      </div>
    </template>
    <script>
      export default {
        methods: {
          childMethod() {
            // fatherMethod父组件方法
            this.$emit('fatherMethod'); 
          }
        }
      };
    </script>
  • 父组件把方法传入子组件中,在子组件里直接调用这个方法:

    // Father.vue
    <template>
      <div style="border: 1px solid red; width: 200px; padding: 10px; margin: 0 auto" >
        我是父组件
        <Child :fatherMethod="fatherMethod"></Child>
        <div style="color: red"> {{ msg }} </div>
      </div>
    </template>
    <script>
      import Child from './Child';
      export default {
          data() {
              return {
                  msg: ''
              }
          },
        components: {
          Child
        },
        methods: {
          fatherMethod() {
            console.log('我的父组件中的方法');
            this.msg = '我的方法被子组件调用了';
          }
        }
      };
    </script>

    父组件可以将事件绑定到子组件标签上,子组件使用 props 接收父组件的事件。

    // Child.vue
    <template>
      <div style="border: 1px solid black; width: 150px; margin: 10px auto">
        我是子组件
        <button @click="childMethod">点击调用父组件方法</button>
      </div>
    </template>
    <script>
      export default {
        props: {
          fatherMethod: {
            type: Function,
            default: null
          }
        },
        methods: {
          childMethod() {
            if (this.fatherMethod) {
              this.fatherMethod();
            }
          }
        }
      };
    </script>

以上三种实现方式效果一致。

调用方法前:

深入讲解Vue中父子组件通信与事件触发

调用方法后:

深入讲解Vue中父子组件通信与事件触发

四、总结

至此,Vue 父子组件之间大部分的操作都涉及到了,我们在程序的开发过程中对于该部分内容可以游刃有余了。

到此这篇关于Vue中父子组件通信与事件触发的文章就介绍到这了,更多相关Vue父子组件通信与事件触发内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Vue.js 相关文章推荐
详解vue中使用transition和animation的实例代码
Dec 12 Vue.js
vue实现简易的双向数据绑定
Dec 29 Vue.js
详解实现vue的数据响应式原理
Jan 20 Vue.js
vue 实现click同时传入事件对象和自定义参数
Jan 29 Vue.js
Vue单页面应用中实现Markdown渲染
Feb 14 Vue.js
Vue包大小优化的实现(从1.72M到94K)
Feb 18 Vue.js
Vue SPA 首屏优化方案
Feb 26 Vue.js
vue使用节流函数的踩坑实例指南
May 20 Vue.js
vite+vue3.0+ts+element-plus快速搭建项目的实现
Jun 24 Vue.js
vue.js Router中嵌套路由的实用示例
Jun 27 Vue.js
vue 实现弹窗关闭后刷新效果
Apr 08 Vue.js
vue3.0 数字翻牌组件的使用方法详解
Apr 20 Vue.js
关于Vue中的options选项
Mar 22 #Vue.js
vue+echarts实现多条折线图
vue使用echarts实现折线图
浅谈Vue的computed计算属性
VUE中的v-if与v-show区别介绍
Mar 13 #Vue.js
Vue.js中v-bind指令的用法介绍
Mar 13 #Vue.js
Vue2.0搭建脚手架
You might like
关于手调机和数调机的选择
2021/03/02 无线电
PHP 创建文件(文件夹)以及目录操作代码
2010/03/04 PHP
php自动加载的两种实现方法
2010/06/21 PHP
用php实现选择排序的解决方法
2013/05/04 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
详解PHP导入导出CSV文件
2014/11/03 PHP
PHP连接MSSQL时nvarchar字段长度被截断为255的解决方法
2014/12/25 PHP
手把手编写PHP框架 深入了解MVC运行流程
2016/09/19 PHP
PHP PDOStatement::fetchObject讲解
2019/02/01 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
PHP后门隐藏的一些技巧总结
2020/11/04 PHP
JavaScript 事件参考手册
2008/12/24 Javascript
新发现一个骗链接的方法(js读取cookies)
2012/01/11 Javascript
CSS+jQuery实现的一个放大缩小动画效果
2013/09/24 Javascript
Angular 根据 service 的状态更新 directive
2016/04/03 Javascript
layer实现关闭弹出层刷新父界面功能详解
2017/11/15 Javascript
微信小程序实践之动态控制组件的显示/隐藏功能
2018/07/18 Javascript
轻量级富文本编辑器wangEditor结合vue使用方法示例
2018/10/10 Javascript
javascript中call,apply,callee,caller用法实例分析
2019/07/24 Javascript
vue-cli2与vue-cli3在一台电脑共存的实现方法
2019/09/25 Javascript
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
2020/12/14 NodeJs
Python操作MongoDB数据库PyMongo库使用方法
2015/04/27 Python
Python打印输出数组中全部元素
2018/03/13 Python
python实现百度语音识别api
2018/04/10 Python
解决matplotlib库show()方法不显示图片的问题
2018/05/24 Python
python实现海螺图片的方法示例
2019/05/12 Python
python之当你发现QTimer不能用时的解决方法
2019/06/21 Python
用Pytorch训练CNN(数据集MNIST,使用GPU的方法)
2019/08/19 Python
python数据类型之间怎么转换技巧分享
2019/08/20 Python
Python如何用filter函数筛选数据
2020/03/05 Python
CSS3 media queries + jQuery实现响应式导航
2016/09/30 HTML / CSS
公务员培训心得体会
2013/12/28 职场文书
医学专业自荐信
2014/06/14 职场文书
个人批评与自我批评范文
2014/10/17 职场文书
2015年大学迎新晚会总结
2015/07/16 职场文书
vue elementUI批量上传文件
2022/04/26 Vue.js