Vue 組件通信的 8 種方式

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"horizontalrule","attrs":{}},{"type":"heading","attrs":{"align":null,"level":1}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/18/18dbc9cb044cb527bc2fb52b4ff21b7a.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"前言","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"    做了半年的公司系統,終於就在前天上線了。後期改BUG時間拖得太長了,出現的大部分BUG 是 前端 與後端 信息不對稱導致的,邏輯性錯誤很不多,用戶體驗上稍微差點,畢竟第一次做這麼大的系統(100w+),通過這次系統的開發,總結了不少經驗,如何更好的跟後端人員協作開發以及如何設計來提高用戶體驗上,之前自己做開發沒關注這方面,只注重功能實現,後期的這塊多補補。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"  項目上線後,接下來就是後期的維護更新了,最近時間終於不是之前那麼忙碌了,簡單的對系統做了下覆盤。 由於項目採用的技術棧是","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Vue","attrs":{}}],"attrs":{}},{"type":"text","text":", 平常開發只注重功能實現了,接下來陸續會對 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" Vue","attrs":{}}],"attrs":{}},{"type":"text","text":" 深入分析,來封裝常用業務組件,以及","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"Vue源碼解析","attrs":{}}],"attrs":{}},{"type":"text","text":"    本章將是對Vue 組件通信的8方法總結,日常開發組件通信密切,熟悉組件通信可以更好的開發業務。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":1}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. 父組件 向 子組件 傳遞值","attrs":{}}]},{"type":"blockquote","content":[{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在父組件中引入子組件","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"註冊子組件","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在頁面中使用,子組件標籤上 動態綁定傳入動態值 / 靜態值","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在子組件中,使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" props","attrs":{}}],"attrs":{}},{"type":"text","text":" 來接受 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 父組件","attrs":{}}],"attrs":{}},{"type":"text","text":" 傳遞過了的值","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"子組件接收的父組件的值分爲引用類型和普通類型兩種:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"普通類型:字符串(String)、數字(Number)、布爾值(Boolean)、空(Null)","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"引用類型:數組(Array)、對象(Object)","attrs":{}}]}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"#父組件\n\n\n\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" Vue","attrs":{}}],"attrs":{}},{"type":"text","text":" 是 單向數據流, ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 子組件","attrs":{}}],"attrs":{}},{"type":"text","text":" 是不能直接 修改 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 父組件","attrs":{}}],"attrs":{}},{"type":"text","text":" 的 值。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. 子組件 向父組件傳遞值","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"子組件通過綁定事件,通過 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" this.$emit('函數名',傳遞參數)","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"#父組件\n\n\n\n\n","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"# 子組件\n\n\n\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3. 父組件 通過 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $refs","attrs":{}}],"attrs":{}},{"type":"text","text":" / ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"$children ","attrs":{}}],"attrs":{}},{"type":"text","text":" 來獲取子組件值","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" $refs","attrs":{}}],"attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"獲取DOM 元素 和 組件實例來獲取組件的屬性和方法。","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過在 子組件 上綁定 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" ref","attrs":{}}],"attrs":{}},{"type":"text","text":" ,使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" this.$refs.refName.子組件屬性 / 子組件方法","attrs":{}}],"attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" $children","attrs":{}}],"attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"當前實例的子組件,它返回的是一個子組件的集合。如果想獲取哪個組件屬性和方法,可以通過 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" this.$children[index].子組件屬性/f方法","attrs":{}}],"attrs":{}}]}]}],"attrs":{}}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"示例 Text 組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"示例 Text2組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"codeinline","content":[{"type":"text","text":"refs","attrs":{}}],"attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n// 通過 $refs 示例來獲取 子組件的屬性和方法\n\n console.log( this.$refs.son.datas) \n\n this.$refs.son.getValue()\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"codeinline","content":[{"type":"text","text":" $children","attrs":{}}],"attrs":{}}]},{"type":"codeblock","attrs":{"lang":"javascript"},"content":[{"type":"text","text":"// 通過 $children 來獲取 子組件的屬性和方法\n this.$children[0].getValue(); // 我是 Test1\n this.$children[1].getTest2(); //我是 Test2\n console.log(`---------${this.$children[1].datas}`); //我是Test2\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"4. 子組件 通過 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $parent","attrs":{}}],"attrs":{}},{"type":"text","text":" 來獲取父組件實例的屬性和方法","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"5. ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $attrs","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $listeners","attrs":{}}],"attrs":{}},{"type":"text","text":" 獲取父組件實例屬性和方法(組件嵌套情況下使用)","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"$attrs","attrs":{}}],"attrs":{}},{"type":"text","text":":包含了父作用域中不被認爲 (且不預期爲) ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" props","attrs":{}}],"attrs":{}},{"type":"text","text":" 的特性綁定 (class 和 style 除外),並且可以通過 v-bind=”","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $attrs","attrs":{}}],"attrs":{}},{"type":"text","text":"” 傳入內部組件。當一個組件沒有聲明任何 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" props","attrs":{}}],"attrs":{}},{"type":"text","text":" 時,它包含所有父作用域的綁定 (class 和 style 除外)。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"$listeners","attrs":{}}],"attrs":{}},{"type":"text","text":":包含了父作用域中的 (不含 .native 修飾符) v-on 事件監聽器。它可以通過 v-on=”","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"$listeners","attrs":{}}],"attrs":{}},{"type":"text","text":"” 傳入內部組件。它是一個對象,裏面包含了作用在這個組件上的所有事件監聽器,相當於子組件繼承了父組件的事件。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"使用場景: 多層嵌套組件的情況下使用,可以避免使用Vuex來做數據處理, 使用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" v-bind=\"$attrs\" v-on=\"$listeners\"","attrs":{}}],"attrs":{}},{"type":"text","text":" 很方便達到業務數據傳遞。","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"父組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"子組件1","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"嵌套子組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"6. 跨組件之間傳值","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"通過新建一個 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" js","attrs":{}}],"attrs":{}},{"type":"text","text":" 文件,導入","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" vue","attrs":{}}],"attrs":{}},{"type":"text","text":" , 導出","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" vue","attrs":{}}],"attrs":{}},{"type":"text","text":" 實例; 然後通過 給導出的實例 上綁定事件","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $emit","attrs":{}}],"attrs":{}},{"type":"text","text":" 事件 , 然後再通過 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" $on","attrs":{}}],"attrs":{}},{"type":"text","text":" 監聽觸發的事件,這樣就可以達到全局組件數據共享。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"使用場景:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"它可以滿足任意場景傳遞數據, ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 父子組件傳值","attrs":{}}],"attrs":{}},{"type":"text","text":" , ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 子父傳值","attrs":{}}],"attrs":{}},{"type":"text","text":" , ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 兄弟組件之間傳值","attrs":{}}],"attrs":{}},{"type":"text","text":" , ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" 跨級組件之間傳值","attrs":{}}],"attrs":{}},{"type":"text","text":" .","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"通信數據比較簡單時,可以採用這種 方案,項目比較龐大,可以採用 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" Vuex","attrs":{}}],"attrs":{}},{"type":"text","text":" .","attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"codeinline","content":[{"type":"text","text":" vue .js","attrs":{}}],"attrs":{}}]},{"type":"codeblock","attrs":{"lang":"js"},"content":[{"type":"text","text":"/*\n * @Description: \n * @Author: ZhangXin\n * @Date: 2021-01-22 15:48:56\n * @LastEditTime: 2021-01-22 15:51:24\n * @LastEditors: ZhangXin\n */\n\n import Vue from 'vue'\n\n export default new Vue()\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"組件A","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"組件C","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"7. Vuex","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這裏就不介紹了,完了單獨寫一篇文章精講","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" Vuex","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"8. ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":"provide","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" inject","attrs":{}}],"attrs":{}},{"type":"text","text":" 實現父組件向子孫孫組件傳值。(層級不限)","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" provide","attrs":{}}],"attrs":{}},{"type":"text","text":" 和 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" inject","attrs":{}}],"attrs":{}},{"type":"text","text":" 這對選項需要一起使用,以允許一個祖先組件向其所有子孫後代注入一個依賴,不論組件層次有多深,並在起上下游關係成立的時間裏始終生效。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"provide","attrs":{}}],"attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"是一個對象或返回一個對象的函數","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"該對象包含可注入其子孫的屬性。","attrs":{}}]}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" inject","attrs":{}}],"attrs":{}},{"type":"text","text":" :","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"是一個字符串數組 或者是一個對象","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"用來在子組件或者子孫組件中注入 ","attrs":{}},{"type":"codeinline","content":[{"type":"text","text":" provide","attrs":{}}],"attrs":{}},{"type":"text","text":" 提供的父組件屬性。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"使用場景:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":" provide/inject可以輕鬆實現跨級訪問父組件的數據","attrs":{}}],"attrs":{}}]}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":"js"},"content":[{"type":"text","text":"# provide\n//對象\nprovide:{\n name:'測試'\n}\n//返回對象的函數\nprovide(){\n return {\n name: '測試'\n }\n}\n\n#inject\ninject:['name']\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"父組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"子組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"子孫組件","attrs":{}}]},{"type":"codeblock","attrs":{"lang":"html"},"content":[{"type":"text","text":"\n\n\n","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"結語","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"❤️關注+點贊+收藏+評論+轉發❤️,原創不易,鼓勵筆者創作更好的文章","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章