<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在vue中, 元件的關係不外乎以下三種:
元件是需要通訊的,在開發中,常用到的通訊方式有:vuex、eventBus、以及props與emit、$parent與$children,除此之外,還有provide與inject、$attrs與$listeners等。
這個相信大家用的很多了,簡單回顧一下:
簡單的使用這裡不贅述,提一下module裡面的名稱空間。
如果希望你的模組具有更高的封裝度和複用性,你可以通過新增 namespaced: true 的方式使其成為帶名稱空間的模組。當模組被註冊後,它的所有 getter、action 及 mutation 都會自動根據模組註冊的路徑調整命名
這樣,在使用的時候我們就可以這樣用了:
這個稱為‘事件匯流排’,簡單看下是怎麼使用的:
首先是初始化一個eventBus,可以繫結到vue原型上,也可以繫結到window物件上,還可以抽出來當做一個模組,在需要的時候再引入。這裡直接繫結到vue原型上:
在需要的元件上建立和刪除事件:
最後就是在需要的地方觸發事件了
這個不用多說了,父子通訊用的最多的應該就是這個了。當然,如果以子元件為跳板,也可以做到祖孫之間通訊,不過比較麻煩。不建議這樣操作。
$parent直接存取的就是父範例,而$children則返回的是範例陣列。所以我一般都是$parent搭配$refs使用。
這兩個可能會用的比較少,來看下官網的介紹:
怎麼理解呢,簡單來講就是,$attrs接收除了prop、style、class之外的所有繫結屬性,$listeners則接收除了被.native修飾的所有繫結事件。具體來看下例子:
<template> <div> <p>父元件</p> <input type="text" v-model="formData.inputValue" /> <p>子元件</p> <Son :inputValue="formData.inputValue" :otherValue="otherValue" @success="success" @input.native="handleInput" v-bind="$attrs" v-on="$listeners" ></Son> </div> </template> <script> import Son from "./son.vue"; export default { components: { Son }, provide() { return { father: this.formData, }; }, data() { return { formData: { inputValue: "123", }, otherValue: 999, }; }, methods: { success(data) { console.log(data); }, handleInput() {}, }, }; </script>
<template> <div> <input type="text" v-model="inputValue" @change="handleChange" /> </div> </template> <script> export default { props: { inputValue: String, }, created() { console.log(this.$attrs, "son---$attrs"); console.log(this.$listeners, "son---$listeners"); }, methods: { handleChange() { this.father.inputValue = this.inputValue; }, }, }; </script>
按照之前的理解,$attrs應該只能接收到otherValue,$listeners則只能接收到success事件,看下列印結果:
結果確實也是這樣的。除此之外,還可傳遞給孫元件:
<template> <div> <input type="text" v-model="inputValue" @change="handleChange" /> <GrandSon v-bind="$attrs" v-on="$listeners"></GrandSon> </div> </template> <script> import GrandSon from "./grandSon.vue"; export default { components: { GrandSon }, props: { inputValue: String, }, created() { console.log(this.$attrs, "son---$attrs"); console.log(this.$listeners, "son---$listeners"); }, methods: { handleChange() { this.father.inputValue = this.inputValue; }, }, }; </script>
<template> <div> <input type="text" v-model="inputValue" @change="handleChange" /> </div> </template> <script> export default { props: { inputValue: String, }, created() { console.log(this.$attrs, "grandSon---$attrs"); console.log(this.$listeners, "grandSon---$listeners"); }, methods: { handleChange() { this.father.inputValue = this.inputValue; }, }, }; </script>
通過這種方式,祖孫之間也實現了通訊。
provide/inject可以在一個祖先元件中向它的所有後輩元件注入一個依賴,只要上下游關係成立就能生效。簡單的理解就是provide是注入資料,inject是獲取資料。所以provide是用於父元件,inject是用於子孫元件。provide應該是一個物件或者返回一個物件的函數,inject應該是一個字串陣列或者一個物件。官網提到這麼一句話:
提示:provide 和 inject 繫結並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的物件,那麼其物件的 property 還是可響應的。
這句話怎麼理解呢?字面理解就是你要想在上下游傳遞的那個資料是可響應的,那麼就應該以物件的形式傳遞,先試一下以基本資料型別的形式傳遞,看下例子:
父元件:
<template> <div> <p>父元件</p> <input type="text" v-model="inputValue" /> <p>子元件</p> <Son></Son> <p>孫元件</p> <GrandSon></GrandSon> </div> </template> <script> import Son from "./son.vue"; import GrandSon from "./grandSon.vue"; export default { components: { Son, GrandSon }, provide() { return { father: this.inputValue, }; }, data() { return { inputValue: "123", }; }, }; </script>
子元件:
<template> <div> <input type="text" v-model="inputValue" @change="handleChange" /> </div> </template> <script> export default { inject: ["father"], data() { return { inputValue: "", }; }, watch: { father(val) { console.log(val, "val"); this.inputValue = val; }, }, created() { console.log(this, "this"); }, methods: { handleChange() { this.father.inputValue = this.inputValue; }, }, }; </script>
在子元件列印this:
可以看到,父元件的inputValue值是被注入到子元件當中的。但卻監聽不到這個father。
然後,我們改成以物件的形式進行注入:
<template> <div> <p>父元件</p> <input type="text" v-model="formData.inputValue" /> <p>子元件</p> <Son></Son> <p>孫元件</p> <GrandSon></GrandSon> </div> </template> <script> import Son from "./son.vue"; import GrandSon from "./grandSon.vue"; export default { components: { Son, GrandSon }, provide() { return { father: this.formData, }; }, data() { return { formData: { inputValue: "123", }, }; }, }; </script>
<template> <div> <input type="text" v-model="inputValue" @change="handleChange" /> </div> </template> <script> export default { inject: ["father"], data() { return { inputValue: "", }; }, watch: { 'father.inputValue'(val){ console.log(val, "val"); this.inputValue = val; }, }, created() { console.log(this, "this"); }, methods: { handleChange() { this.father.inputValue = this.inputValue; }, }, }; </script>
這個時候我們看下列印的this以及效果:
這樣就可以實現資料的響應了。這裡有一個點需要注意,如果在父元件中將整個父元件的this注入到後代元件中,在後代元件中是不能通過深度監聽來監聽這個注入的物件的,會報堆疊溢位的錯誤。所以這裡我用的是this.formData
的形式注入。這樣在子孫元件中可以通過'father.inputValue'
這樣的形式監聽,也可以通過這樣的形式:
father: { handler(val) { console.log(val); }, deep: true, },
至於為什麼會導致這個問題,我們先看下深度監聽的實現方式:
這段註釋什麼意思呢,簡單理解就是vue是通過遞迴遍歷物件裡面的每一個屬性,將是物件的屬性收集起來進行監聽。眾所周知,遞迴是很容易引起堆疊溢位的,而看下this物件就不難理解為什麼會導致堆疊溢位了(太多了,而且是層層巢狀下去的)。
以上就是Vue元件通訊的幾種方式,如果還要在扯一扯,瀏覽器的快取也可以作為一種手段。。。
到此這篇關於vue 元件通訊的幾種方式的文章就介紹到這了,更多相關vue 元件通訊內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45