您好,登錄后才能下訂單哦!
小編給大家分享一下vue組件間怎么進行通信,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
組件通信
盡管子組件可以用this.$parent訪問它的父組件及其父鏈上任意的實例,不過子組件應當避免直接依賴父組件的數據,盡量顯式地使用 props 傳遞數據。
另外,在子組件中修改父組件的狀態是非常糟糕的做法,因為:
這讓父組件與子組件緊密地耦合;
只看父組件,很難理解父組件的狀態。因為它可能被任意子組件修改!理想情況下,只有組件自己能修改它的狀態。
每個Vue實例都是一個事件觸發器:
$on()——監聽事件。
$emit()——把事件沿著作用域鏈向上派送。(觸發事件)
$dispatch()——派發事件,事件沿著父鏈冒泡。
$broadcast()——廣播事件,事件向下傳導給所有的后代。
監聽與觸發
v-on監聽自定義事件:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <!--子組件模板--> <template id="child-template"> <input v-model="msg" /> <button v-on:click="notify">Dispatch Event</button> </template> <!--父組件模板--> <div id="events-example"> <p>Messages: {{ messages | json }}</p> <child v-on:child-msg="handleIt"></child> </div> </body> <script src="js/vue.js"></script> <script> // 注冊子組件 // 將當前消息派發出去 Vue.component('child', { template: '#child-template', data: function (){ return { msg: 'hello' } }, methods: { notify: function() { if(this.msg.trim()){ this.$dispatch('child-msg',this.msg); this.msg = ''; } } } }) // 初始化父組件 // 在收到消息時將事件推入一個數組中 var parent = new Vue({ el: '#events-example', data: { messages: [] }, methods:{ 'handleIt': function(){ alert("a"); } } }) </script> </html>
父組件可以在使用子組件的地方直接用 v-on 來監聽子組件觸發的事件:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="counter-event-example"> <p>{{ total }}</p> <button-counter v-on:increment="incrementTotal"></button-counter> <button-counter v-on:increment="incrementTotal"></button-counter> </div> </body> <script src="js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> Vue.component('button-counter', { template: '<button v-on:click="increment">{{ counter }}</button>', data: function () { return { counter: 0 } }, methods: { increment: function () { this.counter += 1 this.$emit('increment') } }, }) new Vue({ el: '#counter-event-example', data: { total: 0 }, methods: { incrementTotal: function () { this.total += 1 } } }) </script> </html>
在某個組件的根元素上監聽一個原生事件。可以使用 .native 修飾v-on 。例如:
<my-component v-on:click.native="doTheThing"></my-component>
派發事件——$dispatch()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <p>Messages: {{ messages | json }}</p> <child-component></child-component> </div> <template id="child-component"> <input v-model="msg" /> <button v-on:click="notify">Dispatch Event</button> </template> <script src="js/vue.js"></script> <script> // 注冊子組件 Vue.component('child-component', { template: '#child-component', data: function() { return { msg: '' } }, methods: { notify: function() { if (this.msg.trim()) { this.$dispatch('child-msg', this.msg) this.msg = '' } } } }) // 初始化父組件 new Vue({ el: '#app', data: { messages: [] }, events: { 'child-msg': function(msg) { this.messages.push(msg) } } }) </script> </body> </html>
子組件的button元素綁定了click事件,該事件指向notify方法
子組件的notify方法在處理時,調用了$dispatch,將事件派發到父組件的child-msg事件,并給該該事件提供了一個msg參數
父組件的events選項中定義了child-msg事件,父組件接收到子組件的派發后,調用child-msg事件。
廣播事件——$broadcast()
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <input v-model="msg" /> <button v-on:click="notify">Broadcast Event</button> <child-component></child-component> </div> <template id="child-component"> <ul> <li v-for="item in messages"> 父組件錄入了信息:{{ item }} </li> </ul> </template> <script src="js/vue.js"></script> <script> // 注冊子組件 Vue.component('child-component', { template: '#child-component', data: function() { return { messages: [] } }, events: { 'parent-msg': function(msg) { this.messages.push(msg) } } }) // 初始化父組件 new Vue({ el: '#app', data: { msg: '' }, methods: { notify: function() { if (this.msg.trim()) { this.$broadcast('parent-msg', this.msg) } } } }) </script> </body> </html>
和派發事件相反。前者在子組件綁定,調用$dispatch派發到父組件;后者在父組件中綁定,調用$broadcast廣播到子組件。
父子組件之間的訪問
父組件訪問子組件:使用$children或$refs
子組件訪問父組件:使用$parent
子組件訪問根組件:使用$root
$children:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <parent-component></parent-component> </div> <template id="parent-component"> <child-component1></child-component1> <child-component2></child-component2> <button v-on:click="showChildComponentData">顯示子組件的數據</button> </template> <template id="child-component1"> <h3>This is child component 1</h3> </template> <template id="child-component2"> <h3>This is child component 2</h3> </template> <script src="js/vue.js"></script> <script> Vue.component('parent-component', { template: '#parent-component', components: { 'child-component1': { template: '#child-component1', data: function() { return { msg: 'child component 111111' } } }, 'child-component2': { template: '#child-component2', data: function() { return { msg: 'child component 222222' } } } }, methods: { showChildComponentData: function() { for (var i = 0; i < this.$children.length; i++) { alert(this.$children[i].msg) } } } }) new Vue({ el: '#app' }) </script> </body> </html>
$ref可以給子組件指定索引ID:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <parent-component></parent-component> </div> <template id="parent-component"> <!--<child-component1></child-component1> <child-component2></child-component2>--> <child-component1 v-ref:cc1></child-component1> <child-component2 v-ref:cc2></child-component2> <button v-on:click="showChildComponentData">顯示子組件的數據</button> </template> <template id="child-component1"> <h3>This is child component 1</h3> </template> <template id="child-component2"> <h3>This is child component 2</h3> </template> <script src="js/vue.js"></script> <script> Vue.component('parent-component', { template: '#parent-component', components: { 'child-component1': { template: '#child-component1', data: function() { return { msg: 'child component 111111' } } }, 'child-component2': { template: '#child-component2', data: function() { return { msg: 'child component 222222' } } } }, methods: { showChildComponentData: function() { // for (var i = 0; i < this.$children.length; i++) { // alert(this.$children[i].msg) // } alert(this.$refs.cc1.msg); alert(this.$refs.cc2.msg); } } }) new Vue({ el: '#app' }) </script> </body> </html>
效果與$children相同。
$parent:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="app"> <parent-component></parent-component> </div> <template id="parent-component"> <child-component></child-component> </template> <template id="child-component"> <h3>This is a child component</h3> <button v-on:click="showParentComponentData">顯示父組件的數據</button> </template> <script src="js/vue.js"></script> <script> Vue.component('parent-component', { template: '#parent-component', components: { 'child-component': { template: '#child-component', methods: { showParentComponentData: function() { alert(this.$parent.msg) } } } }, data: function() { return { msg: 'parent component message' } } }) new Vue({ el: '#app' }) </script> </body> </html>
如開篇所提,不建議在子組件中修改父組件的狀態。
非父子組件通信
有時候非父子關系的組件也需要通信。在簡單的場景下,使用一個空的 Vue 實例作為中央事件總線:
var bus = new Vue() // 觸發組件 A 中的事件 bus.$emit('id-selected', 1) // 在組件 B 創建的鉤子中監聽事件 bus.$on('id-selected', function (id) { // ... })
看完了這篇文章,相信你對vue組件間怎么進行通信有了一定的了解,想了解更多相關知識,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。