您好,登錄后才能下訂單哦!
這篇文章主要介紹了Vue如何實現組件間通信方式,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
props
父組件可以通過props向下傳遞數據給子組件
靜態的Props
通過為子組件在父組件中的占位符添加特性的方式來達到傳值的目的
動態Props
在模版中要動態的綁定父組件的數據到子模版的props,與綁定任何普通的HTML特性相類似,用v-bind,每當父組件的數據發生變化的時候,該變化會傳導給子組件
props驗證
可以為組件的props指定驗證規則,如果傳入的數據不符合規則,Vue會發出警告
props: { // 基礎類型檢測 (`null` 意思是任何類型都可以) propA: Number, // 多種類型 propB: [String, Number], // 必傳且是字符串 propC: { type: String, required: true }, // 數字,有默認值 propD: { type: Number, default: 100 }, // 數組/對象的默認值應當由一個工廠函數返回 propE: { type: Object, default: function () { return { message: 'hello' } } }, // 自定義驗證函數 propF: { validator: function (value) { return value > 10 } } }
type 可以是(String
,Number
,Boolean
,Function
,Object
,Array
,Symbol
)原生構造器
type也可以是自定義構造函數,使用instenceof檢測
prop是當先綁定的,當父組件的屬性變化是,將傳導給子組件,但是不會反過來,這是為了防止子組件無意修改了父組件的狀態。
修改prop數據
prop 作為初始值傳入后,子組件想把他當作局部數據來用
prop 作為初始值傳入,有子組件處理成其他數據輸出
注意:js中對象和數組是引用類型,指向同一個內存空間,如果prop是一個對象或數組,在子組件內部改變它會影響父組件的狀態
處理方法1:這個時候需要定義一個局部變量,并用prop初始化它,但是局部變量只能接受prop初始值,當父組件的值發生變化的時候,無法接收到最新值
處理方法2:定義一個計算屬性,處理prop值并返回
初始方法3:使用變量存儲prop的初始值,并使用watch來觀察prop的值的變化,當發生變化的時候更新變量的值
$emit
$emit(‘自定義時間名’,要傳送的數據)觸發當前實例上的事件
父組件
<template> <children @addCount="addCount" :count="count"/> <template> <script> import children from "./children"; export default { name:'index', components: {Children}, data () { return { count:0 } }, methods:{ addCount(data){ this.count = data.count; } } } </script>
子組件
<template> <div> <h4>計數器:{{count}}</h4> <button @click='add'>+++</button> </div> </template> <script> export default { name:'children', props:['count'], // 用來接收父組件傳給子組件的數據 methods:{ add() { // 觸發父組件的方法 this.$emit('addCount',{count: count + 1}); } } } </script>
$on
$on(‘事件名’,callback)監聽事件,監聽當前實例上的自定義事件
父組件
<template> <div> <span>{{count}}</span> <children/> </div> <template> <script> import { bus } from '../main.js'; import children from "./children"; export default { name:'index', components: {Children}, data () { return { count:0 } }, mounted(){ bus.$on('addCount',(val)=>{ this.count++; }) } } </script>
子組件
<template> <button @click='add'>count+++</button> </template> <script> import { bus } from '../main.js'; export default { name:'children', methods:{ add() { // 觸發父組件的方法 bus.$emit('addCount',{}); } } } </script>
main文件
export var bus = new Vue();
注意: e m i t 和 emit和 emit和on的事件必須在一個公共的實例上, e m i t 觸 發 的 事 件 emit觸發的事件 emit觸發的事件on才能監聽到。
$parent(不常用)
指向當前組件樹的根實例,如果當前實例沒有父實例,則實例將會指向自己。
$parent既可以接受父組件數據,又可以修改父組件數據,是雙向的。
$parent可以調用父組件的方法
子組件
<template> <button @click='actionParent'>觸發父組件發方法</button> </template> <script> export default { name:'children', methods:{ actionParent() { console.log(this.$parent.name); this.$parent.parentPrint(); // 觸發父組件的方法 } } } </script>
$children(不常用)
指向當前實例的直接子組件,返回的是一個組件的集合。
需要注意: children 并 不 保 證 順 序 , 也 不 是 響 應 式 的 。 如 果 你 發 現 自 己 正 在 嘗 試 使 用 children并不保證順序,也不是響應式的。如果你發現自己正在嘗試使用 children并不保證順序,也不是響應式的。如果你發現自己正在嘗試使用children進行數據綁定,考慮使用一個數組配合v-for來生成子組件,并且使用Array作為真正的來源。
for(let i=0; i<this.$children.length; i++){ console.log(this.$children[i].name); // 輸出子組件的name }
$attrs
包含了父作用域中不作為prop被識別(且獲取)的特性綁定(class,style除外)。當一個組件沒有聲明任何prop時,這里會包含所有父作用域的綁定,并且可以通過v-bind="$attrs"傳入內部組件–在創建高級別的組件時非常有用。
簡單說:接收除了props聲明外的所有綁定屬性(calss,style除外)
上圖的$attrs中只有age,gender兩個屬性{ age: “20”, gender: “man” }
在grandson上通過v-bind="$attrs",可以將屬性繼續向下傳遞,讓grendson也能訪問到父組件的屬性。
這種方式當傳遞多個屬性時會顯得很便捷,不需要一條一條進行綁定。
如果想要添加其他屬性,可繼續綁定屬性,注意:繼續綁定的屬性和$attr中的屬性有重復時,繼續綁定的屬性優先級會更高
$listeners
包含了父級作用域中的(不含.native修飾器的)v-on事件監聽器,他可以通過v-on="$listeners"傳入內部組件–在創建更高層次的組件時非常有用。
簡單說:接收除了帶有.native事件修飾符的所有事件監聽器
child組件綁定了帶有.native的click事件和一個自定義事件,$listeners輸出的結果為:{customEvent:fn}
通過v-on=" listeners"將事件監聽器繼續向下傳遞,讓grandson訪問到事件。并且可以使用emit觸發傳遞下來的事件。
如果想要添加其他事件監聽器,可以繼續綁定事件
注意:繼續綁定的事件和$listeners中的事件有重復的時候,不會被覆蓋。當grandson觸發customEvent時,child和parent的事件都會被觸發,觸發順序類似于冒泡。
使用場景
組件傳值時使用,父親,兒子,孫子三級傳遞參數交互。
對一些UI庫進行二次封裝的時候使用,比如element-ui中的組件不能滿足自己的使用場景時,會二次封裝,但是又想保留它自己的屬性和方法,這個時候使用。
$refs
this.$refs是一個對象,持有當前組件中注冊過ref特性的所有DOM元素和子組件實例
注意:$refs只有在組件渲染完成之后才填充,在初始渲染的時候不能訪問他們,并且它是非響應式的,因此不能用它在模版中做數據綁定。
父組件
<template> <div> <div ref="testDom">123</div> <child ref="child" /> <button @click="openChild" >觸發子組件</button> </div> </template> <script> import Child form './child.vue' export default { components:{ Child }, mounted(){ console.log(this.$refs.testDom) // <div>123</div> console.log(this.$refs.child.name) // 粉刷匠 }, methods:{ openChild(){ this.$refs.child.open(); } } } </script>
子組件
<template> <div>{{name}}</div> </template> <script> export default { data(){ return { name:"粉刷匠" } }, methods:{ open(){ alter("點擊了") } } } </script>
注意:當ref和v-for一起使用的時候,獲取到的將會是一個數組,包含循環數組源。
provide && inject
provide/inject是vue2.2版本之后新增的高級組件,這兩個組件要一起使用。
允許一個祖先組件向其所有的子孫后代注入一個依賴。無論組件層次有多深,并在其上下游關系成立的事件里始終有效。類似于React的上下文。
provide選項是一個對象 或返回一個對象的函數。該對象包含可注入其子孫的property。
inject有下面兩種:
一個字符串數組
一個對象
在可用的注入內容中搜索用的key(字符串/Symbol)
或一個對象
from property是在可用的注入內容中搜索用的key(字符串/Symbol)
default property是降級情況下使用的value
對象的key是本地的綁定名,
value
provide和inject綁定并不是可響應的,這是vue官方刻意為之的。如果你傳入一個可監聽的對象,那么其對象的property還是可響應的。
缺點:在任意層級都能訪問導致數據追蹤比較難,所以provide/inject能不使用就不使用,盡量使用vuex。在組件庫開發的可以使用
副組件
<template> <div class="test"> <son prop="data"></son> </div> </template> <script> export default { name: 'Father', provide: { chontrol: this } data(){ return { name:"啊哈哈" } } }
// 某一級子組件/孫子組件
<template> <div> {{name}} </div> </template> <script> export default { name: 'son', inject: ["chontrol"] props: { name: { type: Object, default: () => ({}), }, } }, } </script>
感謝你能夠認真閱讀完這篇文章,希望小編分享的“Vue如何實現組件間通信方式”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。