本篇文章相對全面并簡潔地介紹了Vue中組件間傳值的幾種方式
一驴党、父傳子
-
標(biāo)簽傳值
-
傳遞:
當(dāng)子組件在父組件中當(dāng)做標(biāo)簽使用的時候矮烹,給子組件綁定一個自定義屬性,值為需要傳遞的數(shù)據(jù)
<son :sex="男"></son>
-
接收:
在子組件內(nèi)部通過props接收嘴办。props有2種接收方式:
-
通過數(shù)組進行接收:
props:["sex"]
- **通過對象進行接收**(推薦): > 通過對象接收可以給接收的值增加數(shù)據(jù)類型限制茸塞,在較大的項目開發(fā)的時候,能利用它避免不少的錯誤描沟。 ```js props:{ sex:{ type:String, //"限制數(shù)據(jù)類型" default: "男", //"默認(rèn)值" required:true //"必須傳遞" } } // 然后就可以{{sex}}進行取值
-
-
-
provide/inject 跨組件傳值
數(shù)據(jù)的流向只能是向下傳遞(包括爺傳孫)
嚴(yán)格的來講是跨組件傳值飒泻,但是也是父傳子的一種方式
-
傳遞:provide
這個配置必須在傳值方進行使用(祖先級),用來定義后代組件所需要的一些屬性和方法
- 第一種寫法:provide是一個函數(shù)吏廉,返回一個對象
provide(){ return{ username:"Hehe" } }
第二種寫法:直接寫成對象:
provide:{ username:"Hehe" }
-
-
接收:inject
必須在后代組建中進行使用泞遗,用來獲取根組件定義的跨組件傳來的數(shù)據(jù)
<h2> 根組件傳來的數(shù)據(jù)為{{username}} </h2>
-
第一種寫法:
inject:["username"]
-
也可以寫成對象(推薦):
同屬性傳值,對象的方式給接收的值增加數(shù)據(jù)類型限制
inject:{ username:{ from:"傳值的組件" default:"默認(rèn)值" }
-
}
```
二:子傳父
-
事件拋發(fā)傳值
利用事件拋發(fā)的傳參原理迟蜜,進行傳值
本質(zhì)是父組件向子組件傳遞一個方法刹孔,子組件調(diào)用這個方法,并傳遞參數(shù)實現(xiàn)子傳父
-
傳遞
在子組件內(nèi)部通過this.$emit("自定義事件的名稱",需要傳遞的參數(shù))來進行數(shù)據(jù)的傳遞
原理:this.$emit 將原先偵聽好的事件進行拋發(fā)娜睛,并傳遞參數(shù)。
this.$emit("sonToFather","子向父傳的值")
-
接收
當(dāng)子組件在父組件中當(dāng)做標(biāo)簽使用的時候給當(dāng)前子組件綁定一個自定義事件卦睹,值為需要接收值得函數(shù)畦戒,這個函數(shù)要特別的注意不允許加()
<Father @sonToFather="callback">{{val}}</Father>
methods:{ callback(val){ this.val = val } },
注意事項:因為此方法基于事件拋發(fā)原理,所以必須先接收才能傳遞结序,二者同時進行亦可障斋。
-
-
作用域插槽
通過將數(shù)據(jù)綁定到組件上的方式,讓父組件得以接收
-
子組件中傳遞
<!-- 在子組件中定義作用域插槽 --> <template> <div id="child"> <!-- 在slot中通過v-bind的方式綁定數(shù)據(jù) --> <slot :title="title"></slot> </div> </template> <script> export default{ name:"Child", data(){ return{ title:"我是子組件的標(biāo)題" } } } </script>
-
-
父組件中接收
<template> <Child> <template v-slot:title="slotProps"> <h2>{{slotProps.title}}</h2> </template> </Child> </template>
三:非父子傳值
-
EventBus——事件總線
原理:給要實現(xiàn)通信的組件雙方綁定同一個新的Vue實例徐鹤,如此便可以調(diào)用同一個實例里的 on 方法傳值垃环,類似于子傳父
缺點:這樣雖然可以做到跨組件傳值,但傳遞方法有一定的不足——綁定一整個實例卻只用到里邊的幾個方法返敬,造成一定的性能浪費
Vue.prototype.$eventBus = new Vue();
-
傳遞
this.$eventBus.$emit("handler","我是傳遞的值")
-
接收
this.$eventBus.$on("handle",(value)=>{ this.value = value; })
-
-
手動封裝事件訂閱(優(yōu)化版)
原理同上遂庄,只不過將用到的方法自己封裝一遍,更節(jié)省性能
// main.js 文件 import observer from "./observer" Vue.prototype.$observer = observer
// observer文件 const eventList = {} const $on = function(eventName,callback){ if(!eventList[eventName]){ eventList[eventName] = [] } eventList[eventName].push(callback) } const $emit = function(eventName,params){ if(eventList[eventName]){ let arr = eventList[eventName]; arr.forEach((cb)=>{ cb(params) }) } } const $off = function(eventName,callback){ if(eventList[eventName]){ if(callback){ let index = eventList[eventName].indexOf(callback); eventList[eventName].splice(index,1) }else{ eventList[eventName].length = 0; } } } export default{ $on, $emit, $off }vuex
vuex
跨組件傳值的最好的解決方案:共享存儲區(qū)域劲赠。放在單獨章節(jié)...