這篇文章帶給大家的內容是關於vue元件通訊的方法介紹(附程式碼),有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
vue 的元件化應該是其最核心的想法了,無論是一個大的頁面還是一個小的按鈕,都可以稱之為元件。基於 Vue 的開發,就是在寫一個個元件,無論是基礎元件還是業務元件,最後都是要拼裝在一起。依照組件的層級關係,可以把組件之間的關係歸納為:父子關係、隔代關係、兄弟關係,無關聯關係。
$ref 、$parent 、$children
基於目前情境的,可以透過 $ref 、$parent 、$children 存取元件實例,可以直接呼叫元件的方法或存取資料。其中 $parent 可以存取目前元件的父元件,$children 可以存取目前元件的所有子元件。雖然 $parent 和 $children 都可以取得元件實例,但是它們無法在跨級或兄弟間通信,這是它們的缺點。
provide 、inject
provide / inject 是 Vue 在 2.2.0 版本後新增的 API。
這對選項需要一起使用,以允許一個祖先組件向其所有子孫後代注入一個依賴,不論組件層次有多深,並在起上下游關係成立的時間裡始終生效。
也就是在父元件中提供一個值,並且在需要使用的子孫元件中註入改值,即:
// Parent.vue export default { provide() { return { name: 'Stone' } } } // Child.vue export default { inject: ['name'], mounted() { console.log(this.name) } }
不只是 Child.vue ,只要是 Parent.vue 的子組件,無論隔多少代,都可以透過這個的方式註入。這種多層次元件透傳的方式可以保證單向資料流的清晰性,例如像使用者資訊這樣的全域訊息,就可以藉助這兩個 API 來完成,而沒有引入第三方函式庫 vuex。
取代Vuex
vuex 是把資料集中管理,然後哪裡需要就在哪裡獲取,按照這個思路,我們可以在根組件 App.vue 中註入全局信息,並且在頁面的任何地方使用。
// App.vue <template> <div> <router-view></router-view> </div> </template> export default { provide() { return { userInfo: this.user } }, data() { return { user: {} } }, methods: { getUserInfo () { $.ajax('/user/info', (data) => { this.user = data }) } } }
把整個 App.vue 的實例 this
對外提供, 這樣其他頁面就可以透過 this.userInfo
來取得使用者資訊。
<template> <div> {{ userInfo }} </div> </template> <script> export default { inject: ['userInfo'] } </script>
$dispatch 、 $broadcast
這兩個API 是Vue 1.0 版本的,$dispatch 用於向上級派發事件,$broadcast 用於向下級廣播事件的,它們在2.0版本中已經被廢棄了。
因為基於元件樹結構的事件流方式有時讓人難以理解,並且在元件結構擴展的過程中會變得越來越脆弱。
不過我們可以自行實作 dispatch 和 broadcast 方法,用於元件的跨層級通訊。它們實現的關鍵在於如何正確找到所要溝通的元件,也就是透過配對元件的 name 選項向下或向上尋找元件。
這兩個方法都需要傳遞3 個參數,第一個參數是要通訊元件的name 選項值,第二個是自訂事件名稱,第三個是要給通訊元件傳遞的值。在 dispatch 裡,透過 while 迴圈不斷向上尋找父元件,直到查找到 componentName 與某個父級元件的 name 選項相符時結束,此時改父元件就是要通訊的元件。 broadcast 方法與 dispatch 類似,是透過 forEach 迴圈向下尋找子元件。最後封裝一個 mixins 來方便重複使用。
// emitter.js function broadcast(componentName, eventName, params) { this.$children.forEach(child => { const name = child.$options.name; if (name === componentName) { child.$emit.apply(child, [eventName].concat(params)); } else { broadcast.apply(child, [componentName, eventName].concat([params])); } }); } export default { methods: { dispatch(componentName, eventName, params) { let parent = this.$parent || this.$root; let name = parent.$options.name; while (parent && (!name || name !== componentName)) { parent = parent.$parent; if (parent) { name = parent.$options.name; } } if (parent) { parent.$emit.apply(parent, [eventName].concat(params)); } }, broadcast(componentName, eventName, params) { broadcast.call(this, componentName, eventName, params); } } };
透過 mixins 混入元件,實現元件間的通訊。
<!-- Parent.vue --> <template> <button @click="handleClick"> 触发事件 <Child></Child> </button> </template> <script> import Emitter from "../assets/js/emitter.js"; import Child from "./Child.vue"; export default { name: "Parent", mixins: [Emitter], created() { this.$on("on-message", message => { console.log(message); }); }, components: { Child }, methods: { handleClick() { this.broadcast("Child", "on-message", "Hello, I am Parent Component"); } } }; </script>
<!-- Child.vue --> <template> <div></div> </template> <script> import Emitter from "../assets/js/emitter.js"; export default { name: "Child", mixins: [Emitter], mounted() { this.$on("on-message", message => { console.log(message); this.dispatch("Parent", "on-message", "Copy that, I am Child Component"); }); } }; </script>
比起Vue 1.0 版本內建的兩個API,自行實作的方法有以下不同:
在vue 中元件的通訊還有其他的手法,例如:
props
、$ emit
<!-- Parent.vue --> <template> <Child :info="info" @update="onUpdateName"></Child> </template> <script> import Child from "./Child.vue"; export default { data() { return { info: { name: "stone" } }; }, components: { Child }, methods: { onUpdateName(name) { this.info.name = name; } } }; </script>
<!-- Child.vue --> <template> <div> <div>{{info.name}}</div> <button @click="handleUpdate">update</button> </div> </template> <script> export default { props: { info: { type: Object, default: {} } }, methods: { handleUpdate() { this.$emit("update", "new-name"); } } }; </script>
父元件將自己的方法傳遞給子元件,子元件呼叫方法傳送資料給父元件使用event bus事件匯流排$attrs 、$listenersVue 2.4 新增的API。
$attrs 包含了父作用域中不作為 prop 被識別 (且獲取) 的特性綁定 (class 和 style 除外)。
$listeners 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監聽器。 Vuex 集中式狀態管理
寫在最後
不同的通信方法適用於不同的場景,既可以透過Vue 內建的API 來通信,也可以透過自訂事件的方式實現通信方法,當應用程式夠複雜情況下,就可以使用Vuex 進行資料管理。
這篇文章到這裡就已經全部結束了,更多其他精彩內容可以關注PHP中文網的JavaScript教學影片專欄!
以上是vue組件通訊的方法介紹(附程式碼)的詳細內容。更多資訊請關注PHP中文網其他相關文章!