摘要:組件之間的通信是我們?cè)陧?xiàng)目中常常碰到的,而選擇合適的通信方式尤為重要,這里總結(jié)下作者在實(shí)際項(xiàng)目中所運(yùn)用到的通信方案,如有遺漏,請(qǐng)大家見(jiàn)諒。示例效果如下兄弟組件同級(jí)別組件相互間的通信,我們可以使用或著。
Vue組件之間的通信是我們?cè)陧?xiàng)目中常常碰到的,而選擇合適的通信方式尤為重要,這里總結(jié)下作者在實(shí)際項(xiàng)目中所運(yùn)用到的通信方案,如有遺漏,請(qǐng)大家見(jiàn)諒。文章代碼具體見(jiàn)DEMO;文章首發(fā)于imondo.cn
父子組件Vue中常見(jiàn)的是父與子組件間的通信,所要用到的關(guān)鍵字段是props和$emit。
props接受父組件傳給子組件信息的字段,它的類(lèi)型:Array
$emit由子組件觸發(fā)事件向上傳播給父級(jí)消息。
示例:
// Parent我是父組件// Child來(lái)自子級(jí)的回答:{{ childMsg }}
我是子組件
父級(jí)來(lái)的信息: {{ msg }}
效果如下:
祖孫組件有時(shí)候我們可能會(huì)碰到組件間的無(wú)限嵌套,這是我們使用props時(shí)無(wú)法向下無(wú)限極傳遞數(shù)據(jù)的,這是我們可以用到provide/inject;provide可以向其子孫組件傳遞數(shù)據(jù),而不關(guān)子孫組件的層級(jí)有多深,使用inject都可以拿到數(shù)據(jù)。詳細(xì)解釋可以參考文檔
示例:
// Grand// Parent我是祖父
我是父組件祖父的信息:{{ grandMsg }}
效果如下:
provide 和 inject 綁定并不是可響應(yīng)的。我們可以通過(guò)傳遞祖父級(jí)的實(shí)例this或著使用observable來(lái)使傳遞的數(shù)據(jù)是響應(yīng)的。
// Grand// Child我是祖父
我是子組件
爺爺?shù)膶?shí)例信息: {{ grandVmMsg }}
效果如下:
使用observable讓一個(gè)對(duì)象可響應(yīng)。Vue 內(nèi)部會(huì)用它來(lái)處理 data 函數(shù)返回的對(duì)象。
示例:
// Grand provide() { this.read = Vue.observable({ msg: "" }) return { read: this.read }; }
效果如下:
兄弟組件同級(jí)別組件相互間的通信,我們可以使用EventBus或著Vuex。
簡(jiǎn)單的EventBus示例:
// Bus.js import Vue from "vue"; export default new Vue(); // Child// ChildOne我是子組件一
我是子組件二
兄弟叫我:{{ msg }}
效果如下:
v-model是我們用ElementUI常見(jiàn)的表單綁定值方式;可以直接修改子組件修改父組件傳入的值,簡(jiǎn)化了我們組件通信的邏輯。
示例:
// ModelCom// Home
效果如下:
sync修飾符也可以是我們的prop進(jìn)行雙向綁定。
它需要我們?cè)谧咏M件內(nèi)觸發(fā)this.$emit("update:prop", val)事件
// ModelCom ... props: ["value"], methods: { handleChange(e) { const value = e.target.value; // 觸發(fā)更新 this.$emit("update:value", value); } } // Home
效果如下:
$children與$parent我們可以在組件中通過(guò)當(dāng)前的實(shí)例對(duì)象訪問(wèn)到組件的$children和$parent來(lái)找到各自組件的父級(jí)組件或子級(jí)組件實(shí)例。
示例:
// Child... $attrs與$listeners我是子組件
來(lái)自父組件的msg: {{ msg }}
$attrs可以通過(guò) v-bind="$attrs" 將組件上的特新都(class 和 style 除外)傳入內(nèi)部組件;傳入的值與inheritAttrs的設(shè)置有關(guān),通常封裝高級(jí)組件。
當(dāng)我們inheritAttrs 設(shè)置 true;組件渲染DOM時(shí)寫(xiě)在組件的特性會(huì)渲染上去;
$listeners包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽(tīng)器。它可以通過(guò) v-on="$listeners" 傳入內(nèi)部組件。
具體詳細(xì)可見(jiàn)文檔
示例:
// Attr... // HomeAttr
這是$attrs:{{ placeholder }}
這是$listeners:{{ test }}
效果如下:
通過(guò)封裝查找組件通過(guò)封裝函數(shù)來(lái)向上或向下派發(fā)事件參考見(jiàn)Vue.js組件精講
// 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); } } };通過(guò)封裝函數(shù)來(lái)查找指定任意組件參考見(jiàn)Vue.js組件精講
// 由一個(gè)組件,向上找到最近的指定組件 function findComponentUpward (context, componentName) { let parent = context.$parent; let name = parent.$options.name; while (parent && (!name || [componentName].indexOf(name) < 0)) { parent = parent.$parent; if (parent) name = parent.$options.name; } return parent; } export { findComponentUpward }; // 由一個(gè)組件,向上找到所有的指定組件 function findComponentsUpward (context, componentName) { let parents = []; const parent = context.$parent; if (parent) { if (parent.$options.name === componentName) parents.push(parent); return parents.concat(findComponentsUpward(parent, componentName)); } else { return []; } } export { findComponentsUpward }; // 由一個(gè)組件,向下找到所有指定的組件 function findComponentsDownward (context, componentName) { return context.$children.reduce((components, child) => { if (child.$options.name === componentName) components.push(child); const foundChilds = findComponentsDownward(child, componentName); return components.concat(foundChilds); }, []); } export { findComponentsDownward }; // 由一個(gè)組件,找到指定組件的兄弟組件 function findBrothersComponents (context, componentName, exceptMe = true) { let res = context.$parent.$children.filter(item => { return item.$options.name === componentName; }); let index = res.findIndex(item => item._uid === context._uid); if (exceptMe) res.splice(index, 1); return res; } export { findBrothersComponents };總結(jié)項(xiàng)目中組件的通信方式大概常用的是上面幾種方案,我們可以通過(guò)不同的方式來(lái)實(shí)現(xiàn)組件通信,但是選擇合適組件通信方式可以使我們事半功倍。寫(xiě)的不當(dāng)之處,望指正~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/104274.html
摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥(niǎo)雀呼晴,侵曉窺檐語(yǔ)。葉上初陽(yáng)乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門(mén),久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
摘要:五六月份推薦集合查看最新的請(qǐng)點(diǎn)擊集前端最近很火的框架資源定時(shí)更新,歡迎一下。蘇幕遮燎沈香宋周邦彥燎沈香,消溽暑。鳥(niǎo)雀呼晴,侵曉窺檐語(yǔ)。葉上初陽(yáng)乾宿雨,水面清圓,一一風(fēng)荷舉。家住吳門(mén),久作長(zhǎng)安旅。五月漁郎相憶否。小楫輕舟,夢(mèng)入芙蓉浦。 五、六月份推薦集合 查看github最新的Vue weekly;請(qǐng)::點(diǎn)擊::集web前端最近很火的vue2框架資源;定時(shí)更新,歡迎 Star 一下。 蘇...
摘要:項(xiàng)目中,組件是項(xiàng)目的基石,每個(gè)頁(yè)面都是組件來(lái)組裝起來(lái),我司沒(méi)有自己的組件庫(kù),選用的是組件庫(kù),在它的基礎(chǔ)上再次封裝。部分代碼三級(jí)效果如下總結(jié)組件是項(xiàng)目的積木條,公用組件的封裝成功與否其實(shí)是對(duì)項(xiàng)目的開(kāi)發(fā)效率有直接影響。 vue項(xiàng)目中,組件是項(xiàng)目的基石,每個(gè)頁(yè)面都是組件來(lái)組裝起來(lái),我司沒(méi)有自己的組件庫(kù),選用的是ElementUI組件庫(kù),在它的基礎(chǔ)上再次封裝。 可編輯表格 由于是后臺(tái)管理項(xiàng)目,...
摘要:本文總結(jié)了組件間通信的幾種方式,如和,以通俗易懂的實(shí)例講述這其中的差別及使用場(chǎng)景,希望對(duì)小伙伴有些許幫助。狀態(tài)改變提交操作方法。 前言 組件是 vue.js最強(qiáng)大的功能之一,而組件實(shí)例的作用域是相互獨(dú)立的,這就意味著不同組件之間的數(shù)據(jù)無(wú)法相互引用。一般來(lái)說(shuō),組件可以有以下幾種關(guān)系:showImg(https://segmentfault.com/img/remote/146000001...
閱讀 667·2023-04-25 15:49
閱讀 3121·2021-09-22 15:13
閱讀 1258·2021-09-07 10:13
閱讀 3481·2019-08-29 18:34
閱讀 2562·2019-08-29 15:22
閱讀 512·2019-08-27 10:52
閱讀 689·2019-08-26 18:27
閱讀 3023·2019-08-26 13:44