本篇資料來於官方文檔:數組
http://cn.vuejs.org/guide/components.html#u7236_u5B50_u7EC4_u4EF6_u901A_u4FE1
app
本文是在官方文檔的基礎上,更加細緻的說明,代碼更多更全。ide
簡單來講,更適合新手閱讀ui
(二十七)父子組件通訊this
①訪問子組件、父組件、根組件;
this.$parent 訪問父組件spa
this.$children 訪問子組件(是一個數組).net
this.$root 根實例的後代訪問根實例code
示例代碼:
- <div id="app">
- 父組件:
- <input v-model="val"><br/>
- 子組件:
- <test :test="val"></test>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- data: {
- val: 1
- },
- components: {
- test: {
- props: ['test'],
- template: "<input @keyup='findParent' v-model='test'/>",
- methods: {
- findParent: function () {
- console.log(this.$parent); //訪問根組件
- console.log(this.$parent.val); //訪問根組件的val屬性
- console.log(this.$parent.$children.indexOf(this)); //查看當前可否在其父組件的子組件中找到索引
- console.log(this.$parent === this.$root); //查看父組件和根組件是否是全等的(由於他的父組件就是根組件)
- }
- }
- }
- }
- });
- </script>
當在子組件的輸入框按鍵彈起時,顯示內容依次爲:
父組件、父組件的輸入框的值(默認狀況是1)、0(表示是父組件的children屬性中的第一個元素)、true(因爲父組件就是根組件,因此是全等的);
經過這樣的方法,能夠在組件樹中進行互動。
②自定義事件:
首先,事件須要放置在events屬性之中,而不是放置在methods屬性中(新手很容易犯的錯誤),只能觸發events屬性中的事件,而methods屬性中的事件是沒法觸發的。
事件 |
說明 |
$on(事件名) |
事件名的類型是字符串(下同),調用它能夠經過this.$on()來調用; |
$emit(事件名, 參數) |
用於觸發事件,參數是用於傳遞給事件的參數。這個用於觸發同級事件(當前組件的) |
$dispatch(事件名, 參數) |
①向上派發事件,用於向父組件傳播。 ②會首先觸發當前組件的同名事件(若是有); ③而後會向上冒泡,當遇到第一個符合的父組件的事件後觸發並中止; ④當父組件的事件的返回值設爲true會繼續冒泡去找下一個。 |
$broadcast(事件名, 參數) |
①向下廣播事件,用於向全部子組件傳播。 ②默認狀況是僅限子組件; ③子組件事件的返回值是true,纔會繼續向該子組件的孫組件派發; ④不會觸發自身同名事件; |
其次,向上派發和向下廣播有所區別:向上派發會觸發自身同名事件,而向下廣播不會;
第三,向上派發和向下廣播默認只會觸發直系(子或者父,不包括祖先和孫)的事件,除非事件返回值爲true,纔會繼續在這一條線上繼續。
第四,事件不能顯式的經過 this.事件名 來調用它。
示例代碼:
- <div id="app">
- 父組件:
- <button @click="parentClick">點擊向下傳播broadcast</button>
- <br/>
- 子組件1:
- <children1></children1>
- <br/>
- 另外一個子組件1:
- <another-children1></another-children1>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- data: {
- val: 1
- },
- methods: {
- parentClick: function () {
- this.$broadcast("parentClick", "abc");
- }
- },
- events: {
- childrenClick: function () {
- console.log("childrenClick-Parent");
- },
- parentClick: function () {
- console.log("parentClick-Parent");
- return true;
- }
- },
- components: {
- children1: { //這個無返回值,不會繼續派發
- props: ['test'],
- template: "<button>children1</button></br>子組件2:<children2></children2>",
- events: {
- childrenClick: function () {
- console.log("childrenClick-children1");
- },
- parentClick: function (msg) {
- console.log("parentClick-Children1");
- console.log("message:" + msg);
- }
- },
- components: {
- children2: {
- props: ['test'],
- template: "<button @click='findParent'>children-Click</button>",
- methods: {
- findParent: function () {
- this.$dispatch('childrenClick');
- }
- },
- events: {
- childrenClick: function () {
- console.log("childrenClick-children2");
- },
- parentClick: function (msg) {
- console.log("parentClick-Children2");
- console.log("message:" + msg);
- }
- }
- }
- }
- },
- anotherChildren1: { //這個是返回值爲true,會繼續向子組件的子組件派發
- props: ['test'],
- template: "<button>anotherChildren1</button></br>另外一個子組件2:<another-children2></another-children2>",
- events: {
- childrenClick: function () {
- console.log("childrenClick-anotherChildren1");
- return true;
- },
- parentClick: function (msg) {
- console.log("parentClick-anotherChildren1");
- console.log("message:" + msg);
- return true;
- }
- },
- components: {
- anotherChildren2: {
- props: ['test'],
- template: "<button @click='findParent'>anotherChildren2-Click</button>",
- methods: {
- findParent: function () {
- this.$dispatch('childrenClick');
- }
- },
- events: {
- childrenClick: function () {
- console.log("childrenClick-anotherChildren2");
- },
- parentClick: function (msg) {
- console.log("parentClick-anotherChildren2");
- console.log("message:" + msg);
- }
- }
- }
- }
- }
-
- }
- });
- </script>
- },
- parentClick: function () {
- console.log("parentClick-anotherChildren2");
- }
- }
- }
- }
- }
-
- }
- });
- </script>
說明:
【1】點擊父組件的按鈕,會向下廣播,而後觸發子組件1自己,另一個子組件1,以及另外一個子組件2;
【2】點擊子組件2的按鈕,會觸發子組件2的事件和子組件1的事件,但不會觸發父組件的按鈕;
【3】點擊另外一個子組件2的按鈕,會觸發另外一個子組件2的事件,另外一個子組件1的事件和父組件的事件(由於另外一個子組件1的事件的返回值爲true);
③使用v-on綁定自定義事件:
【1】簡單來講,子組件觸發某個事件(events裏的方法)時,父組件也會執行某個方法(父組件methods裏的方法)。
【2】觸發的綁定寫在模板之中(即被替換的那個template模板中),能夠多個子組件的事件綁定一個父組件的方法,或者不一樣子組件的事情綁定不一樣父組件的方法,可是不能同一個子組件事件綁定多個父組件的方法。
【3】子組件派發消息傳遞的參數,即便子組件的事件沒有參數,也不影響將參數傳遞給父組件的方法(即父組件的方法能夠接受到子組件方法獲取的參數)
如示例:
- <div id="app">
- 父組件:
- <button>點擊向下傳播broadcast</button>
- <br/>
- 子組件1:
-
- <children v-on:test="parent" @test2="another"></children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- data: {
- val: 1
- },
- methods: {
- parent: function (arg) {
- console.log(arg);
- console.log("the first method with test event");
- },
- another: function () {
- console.log("another method");
- }
- },
- components: {
- children: { //這個無返回值,不會繼續派發
- props: ['test'],
- template: "<button @click='childClick'>children1</button></br><button @click='childClick2'>children1</button>",
- methods: {
- childClick: function () {
- this.$emit("test", 'the argument for dispatch');
- },
- childClick2: function () {
- this.$emit("test2");
- }
- },
- events: {
- test: function () {
- console.log("test");
- },
- test2: function () {
- console.log("test2");
- }
- }
- }
- }
- });
- </script>
④子組件索引
簡單來講:就是能夠直接從索引獲取到子組件,而後就能夠調用各個子組件的方法了。
添加索引方法是:在標籤裏添加v-ref:索引名
調用組件方法是:vm.$ref.索引名
也能夠直接在父組件中使用this.$ref.索引名
這個時候,就能夠得到組件了,而後經過組件能夠調用他的方法,或者是使用其數據。
示例代碼:
- <div id="app">
- 父組件:
- <button @click="todo">觸發子組件的事件</button>
- <br/>
- 子組件1:
-
- <children v-ref:child></children>
- </div>
- <script>
- var vm = new Vue({
- el: '#app',
- methods: {
- todo: function () {
- this.$refs.child.fromParent(); //經過索引調用子組件的fromParent方法
- }
- },
- components: {
- children: { //這個無返回值,不會繼續派發
- props: ['test'],
- template: "<button>children1</button>",
- methods: {
- fromParent: function () {
- console.log("happened fromParent by ref");
- }
- }
- }
- }
- });
- </script>