版权声明:出处http://blog.csdn.net/qq20004604

 

目录(?)[+]

 

本篇资料来于官方文档:

http://cn.vuejs.org/guide/components.html#u7236_u5B50_u7EC4_u4EF6_u901A_u4FE1

本文是在官方文档的基础上,更加细致的说明,代码更多更全。

简单来说,更适合新手阅读

(二十七)父子组件通信

①访问子组件、父组件、根组件;

this.$parent    访问父组件

this.$children   访问子组件(是一个数组)

this.$root            根实例的后代访问根实例

示例代码:

  1. <div id="app">
  2. 父组件:
  3. <input v-model="val"><br/>
  4. 子组件:
  5. <test :test="val"></test>
  6. </div>
  7. <script>
  8. var vm = new Vue({
  9. el: '#app',
  10. data: {
  11. val: 1
  12. },
  13. components: {
  14. test: {
  15. props: ['test'],
  16. template: "<input @keyup='findParent' v-model='test'/>",
  17. methods: {
  18. findParent: function () {
  19. console.log(this.$parent);  //访问根组件
  20. console.log(this.$parent.val);  //访问根组件的val属性
  21. console.log(this.$parent.$children.indexOf(this));  //查看当前能否在其父组件的子组件中找到索引
  22. console.log(this.$parent === this.$root);   //查看父组件和根组件是不是全等的(因为他的父组件就是根组件)
  23. }
  24. }
  25. }
  26. }
  27. });
  28. </script>

当在子组件的输入框按键弹起时,显示内容依次为:

父组件、父组件的输入框的值(默认情况是1)、0(表示是父组件的children属性中的第一个元素)、true(由于父组件就是根组件,所以是全等的);

通过这样的方法,可以在组件树中进行互动。

②自定义事件:

首先,事件需要放置在events属性之中,而不是放置在methods属性中(新手很容易犯的错误),只能触发events属性中的事件,而methods属性中的事件是无法触发的。

事件

说明

$on(事件名)

事件名的类型是字符串(下同),调用它可以通过this.$on()来调用;

$emit(事件名, 参数)

用于触发事件,参数是用于传递给事件的参数。这个用于触发同级事件(当前组件的)

$dispatch(事件名, 参数)

①向上派发事件,用于向父组件传播。

②会首先触发当前组件的同名事件(如果有);

③然后会向上冒泡,当遇到第一个符合的父组件的事件后触发并停止;

④当父组件的事件的返回值设为true会继续冒泡去找下一个。

$broadcast(事件名, 参数)

①向下广播事件,用于向所有子组件传播。

②默认情况是仅限子组件;

③子组件事件的返回值是true,才会继续向该子组件的孙组件派发;

④不会触发自身同名事件;

其次,向上派发和向下广播有所区别:向上派发会触发自身同名事件,而向下广播不会;

第三,向上派发和向下广播默认只会触发直系(子或者父,不包括祖先和孙)的事件,除非事件返回值为true,才会继续在这一条线上继续。

第四,事件不能显式的通过 this.事件名 来调用它。

示例代码:

  1. <div id="app">
  2. 父组件:
  3. <button @click="parentClick">点击向下传播broadcast</button>
  4. <br/>
  5. 子组件1:
  6. <children1></children1>
  7. <br/>
  8. 另一个子组件1:
  9. <another-children1></another-children1>
  10. </div>
  11. <script>
  12. var vm = new Vue({
  13. el: '#app',
  14. data: {
  15. val: 1
  16. },
  17. methods: {
  18. parentClick: function () {
  19. this.$broadcast("parentClick", "abc");
  20. }
  21. },
  22. events: {
  23. childrenClick: function () {
  24. console.log("childrenClick-Parent");
  25. },
  26. parentClick: function () {
  27. console.log("parentClick-Parent");
  28. return true;
  29. }
  30. },
  31. components: {
  32. children1: {    //这个无返回值,不会继续派发
  33. props: ['test'],
  34. template: "<button>children1</button></br>子组件2:<children2></children2>",
  35. events: {
  36. childrenClick: function () {
  37. console.log("childrenClick-children1");
  38. },
  39. parentClick: function (msg) {
  40. console.log("parentClick-Children1");
  41. console.log("message:" + msg);
  42. }
  43. },
  44. components: {
  45. children2: {
  46. props: ['test'],
  47. template: "<button @click='findParent'>children-Click</button>",
  48. methods: {
  49. findParent: function () {
  50. this.$dispatch('childrenClick');
  51. }
  52. },
  53. events: {
  54. childrenClick: function () {
  55. console.log("childrenClick-children2");
  56. },
  57. parentClick: function (msg) {
  58. console.log("parentClick-Children2");
  59. console.log("message:" + msg);
  60. }
  61. }
  62. }
  63. }
  64. },
  65. anotherChildren1: { //这个是返回值为true,会继续向子组件的子组件派发
  66. props: ['test'],
  67. template: "<button>anotherChildren1</button></br>另一个子组件2:<another-children2></another-children2>",
  68. events: {
  69. childrenClick: function () {
  70. console.log("childrenClick-anotherChildren1");
  71. return true;
  72. },
  73. parentClick: function (msg) {
  74. console.log("parentClick-anotherChildren1");
  75. console.log("message:" + msg);
  76. return true;
  77. }
  78. },
  79. components: {
  80. anotherChildren2: {
  81. props: ['test'],
  82. template: "<button @click='findParent'>anotherChildren2-Click</button>",
  83. methods: {
  84. findParent: function () {
  85. this.$dispatch('childrenClick');
  86. }
  87. },
  88. events: {
  89. childrenClick: function () {
  90. console.log("childrenClick-anotherChildren2");
  91. },
  92. parentClick: function (msg) {
  93. console.log("parentClick-anotherChildren2");
  94. console.log("message:" + msg);
  95. }
  96. }
  97. }
  98. }
  99. }
  100. }
  101. });
  102. </script>
  103. },
  104. parentClick: function () {
  105. console.log("parentClick-anotherChildren2");
  106. }
  107. }
  108. }
  109. }
  110. }
  111. }
  112. });
  113. </script>

说明:

【1】点击父组件的按钮,会向下广播,然后触发子组件1本身,另外一个子组件1,以及另一个子组件2;

【2】点击子组件2的按钮,会触发子组件2的事件和子组件1的事件,但不会触发父组件的按钮;

【3】点击另一个子组件2的按钮,会触发另一个子组件2的事件,另一个子组件1的事件和父组件的事件(因为另一个子组件1的事件的返回值为true);

③使用v-on绑定自定义事件:

【1】简单来说,子组件触发某个事件(events里的方法)时,父组件也会执行某个方法(父组件methods里的方法)。

【2】触发的绑定写在模板之中(即被替换的那个template模板中),可以多个子组件的事件绑定一个父组件的方法,或者不同子组件的事情绑定不同父组件的方法,但是不能同一个子组件事件绑定多个父组件的方法。

【3】子组件派发消息传递的参数,即使子组件的事件没有参数,也不影响将参数传递给父组件的方法(即父组件的方法可以接受到子组件方法获取的参数)

如示例:

  1. <div id="app">
  2. 父组件:
  3. <button>点击向下传播broadcast</button>
  4. <br/>
  5. 子组件1:
  6. <!--绑定写在这里,可以多个绑定同一个,或者不同绑定不同的,但不能一个绑定多个-->
  7. <children v-on:test="parent" @test2="another"></children>
  8. </div>
  9. <script>
  10. var vm = new Vue({
  11. el: '#app',
  12. data: {
  13. val: 1
  14. },
  15. methods: {
  16. parent: function (arg) {
  17. console.log(arg);
  18. console.log("the first method with test event");
  19. },
  20. another: function () {
  21. console.log("another method");
  22. }
  23. },
  24. components: {
  25. children: {    //这个无返回值,不会继续派发
  26. props: ['test'],
  27. template: "<button @click='childClick'>children1</button></br><button @click='childClick2'>children1</button>",
  28. methods: {
  29. childClick: function () {
  30. this.$emit("test", 'the argument for dispatch');
  31. },
  32. childClick2: function () {
  33. this.$emit("test2");
  34. }
  35. },
  36. events: {
  37. test: function () {
  38. console.log("test");
  39. },
  40. test2: function () {
  41. console.log("test2");
  42. }
  43. }
  44. }
  45. }
  46. });
  47. </script>

④子组件索引

简单来说:就是可以直接从索引获取到子组件,然后就可以调用各个子组件的方法了。

添加索引方法是:在标签里添加v-ref:索引名

调用组件方法是:vm.$ref.索引名

也可以直接在父组件中使用this.$ref.索引名

这个时候,就可以获得组件了,然后通过组件可以调用他的方法,或者是使用其数据。

示例代码:

  1. <div id="app">
  2. 父组件:
  3. <button @click="todo">触发子组件的事件</button>
  4. <br/>
  5. 子组件1:
  6. <!--绑定写在这里,可以多个绑定同一个,或者不同绑定不同的,但不能一个绑定多个-->
  7. <children v-ref:child></children>
  8. </div>
  9. <script>
  10. var vm = new Vue({
  11. el: '#app',
  12. methods: {
  13. todo: function () {
  14. this.$refs.child.fromParent();  //通过索引调用子组件的fromParent方法
  15. }
  16. },
  17. components: {
  18. children: {    //这个无返回值,不会继续派发
  19. props: ['test'],
  20. template: "<button>children1</button>",
  21. methods: {
  22. fromParent: function () {
  23. console.log("happened fromParent by ref");
  24. }
  25. }
  26. }
  27. }
  28. });
  29. </script>

Vuejs——(10)组件——父子组件通信的更多相关文章

  1. vue组件父子间通信之综合练习--假的聊天室

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. vue组件-构成组件-父子组件相互传递数据

    组件对于vue来说非常重要,学习学习了基础vue后,再回过头来把组件弄透! 一.概念 组件意味着协同工作,通常父子组件会是这样的关系:组件 A 在它的模版中使用了组件 B . 它们之间必然需要相互通信 ...

  3. vue组件父子组件传递引用类型数据

    今天在写分页功能时,发现父子组件传值时,子组件监听不到父组件中数据的变化,传递的是一个引用类型的数据 其原因是引用类型共用一个内存地址,父子组件用的是同一个对象,故子组件监听不到变化,此时就需要做一个 ...

  4. vue组件父子间通信02

    三.组件间通信($parent $refs) 父组件要想获取子组件的数据:①在调用子组件的时候,指定ref属性<child-component ref="mySon"> ...

  5. Vue组件父子间通信01

    子组件传递数据 用户已经登录 父组件接收数据 并显示列表,未登录不显示列表 /* 有两个组件,分别是main-component,header-component.main-component是由he ...

  6. Angular组件——父子组件通讯

    Angular组件间通讯 组件树,1号是根组件AppComponent. 组件之间松耦合,组件之间知道的越少越好. 组件4里面点击按钮,触发组件5的初始化逻辑. 传统做法:在按钮4的点击事件里调用组件 ...

  7. vue全局组件-父子组件传值

    全局组件注册方式:Vue.component(组件名,{方法}) demo: 子组件:upload.vue <template> <div > <div class=&q ...

  8. vue组件父子组件之间传递数据

    举个栗子: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

  9. React之父子组件之间传值

    1.新增知识点 /** React中的组件: 解决html 标签构建应用的不足. 使用组件的好处:把公共的功能单独抽离成一个文件作为一个组件,哪里里使用哪里引入. 父子组件:组件的相互调用中,我们把调 ...

随机推荐

  1. scrapy-pipeline的方法

    scrapy中多个pipeline作用: 一个项目可能需要爬取多个网站,根据每个网站的数据量(处理方式)不同,可创建多个管道 pipeline class SpideranythingPipeline ...

  2. 转载:Opencv调整运行窗口图片的大小

    本文来自:http://blog.csdn.net/cumtml/article/details/52807961 Opencv在运算时显示图片问题 总结在opencv中,图片显示的问题.简要解决图片 ...

  3. e1000

    http://blog.csdn.net/sdulibh/article/details/41826221 http://blog.csdn.net/evenness/article/details/ ...

  4. python学习笔记(五)- 文件操作

    1.读文件f = open('word.txt',encoding='utf8')  #默认打开当前目录下的文件,打开其它目录用绝对路径#f = open('word.txt',encoding='u ...

  5. springboot 整合 mybatis

    spirngboot 整合mybatis有两种方式 第一种 无配置文件注解版,这一种符合springboot的风格 第二种 有配置文件xml版本,这一种就是传统的模式 无论哪一种,首先都需要加入MyS ...

  6. mybatis 根据参数映射对应模型

    ORM 框架的优势在于能让我们利用面向对象的思维去操作数据库, hibernate 作为重量级的 ORM 框架对面向对象的支持很强大.作为半自动化的 mybatis ,对面向对象的支持也是很完备的.这 ...

  7. Python设计模式 - UML - 用例图(Use Case Diagram)

    简介 用例图主要是从用户的角度出发对软件产品的功能及执行者进行描述的. 用例图是从需求分析到软件交付的第一步,图示化展示参与者与参与者之间.参与者与用例之间.用例与用例之间的关系,帮助开发人员更好的理 ...

  8. extern和include的作用

    首先要搞清楚的是.h头文件中都是一些声明性的语句,是不分配内存的,所以头文件中有对函数的声明,有define语句,有没有实例化的结构体定义,但是没有对变量的定义(比如 int a),有的只是对外变量的 ...

  9. 100-days: seventeen

    Title: How 'Bohemian Rhapsody(波西米亚狂想曲)' ended up in 'Wayne's World(反斗智多星)' and became a phenomenon(现 ...

  10. SSM框架整合的其它方式

    ---------------------siwuxie095                                 SSM 框架整合的其它方式         1.主要是整合 Spring ...