首頁  >  文章  >  web前端  >  vue中不同情況怎麼進行通訊?方式分享

vue中不同情況怎麼進行通訊?方式分享

青灯夜游
青灯夜游轉載
2022-04-20 20:39:142440瀏覽

vue中不同情況下怎麼進行通訊?以下這篇文章給大家分析一下vue中不同情況下的通訊方式,希望對大家有幫助!

vue中不同情況怎麼進行通訊?方式分享

其實對於vue中元件通訊這件事大家也都不陌生。甚至張口就來,畢竟這也是面試中的常會問到的。由於之前沒有進行過細緻的考慮,在寫小項目的時候遇到了組件中通訊的需求,然後上來就寫,結果發現沒有用,查了好久才知道那種方式不適用這樣情況。所以經過這次事情決定要寫篇文章,對於通訊方式進行更清楚更細緻的分類,畢竟不是每種通訊方式都適用於所有場景。 (學習影片分享:vuejs教學

同視窗(也就是同一個瀏覽器同一個頁籤內)

##同瀏覽器同頁簽內主要涉及的就是父子元件的傳值。

vuex:狀態管理器:適用一個專案裡的任何元件,包容性極強

對於狀態管理器的概念大家應該也不會陌生。


    多個元件可以共用一個或多個狀態值。不管組件的層級有多深都可以正常存取。所以這是一種官方直接支援的通訊方式。
  • 注意:
  • 對於小型單頁應用而言,該選擇並不是很建議,對於小型專案而言使用vuex反而會變得更加繁瑣,就像是一個75斤150cm的人,穿了一件170cm110斤人的衣服一樣,看著就很鬆鬆垮垮撐不起來。

provide / inject (寫法基於v2.2.1以上版本):適用N級元件,但是必須是單線傳承的那種

#這對選項需要一起使用,以允許一個祖先組件向其所有子孫後代注入一個依賴,不論組件層次有多深,並在其上下游關係成立的時間裡始終生效。

    就是相當於有N層樓的樓房,最頂層的是父級組件,每層樓之間會公用一個管子,這個管子就是provide。而管子在每層樓都有一個出口叫:inject
  • 注意:
  • provide 和 inject 綁定並不是可回應的。不過如果你傳入了一個可監聽的對象,那麼其對象的 property 還是可回應的。
  • 讓咱們來看看程式碼
  • // parent.vue
    // 此处忽略template模板的东西
    <script>
    export default {
        name: &#39;parent&#39;,
        // provide有两种写法
        // 第一种
        provide: {
            a: 1,
            b: 2
        }
        // 第二种
        provide() {
            return {
                a: 1,
                b: 2
            }
        }
    }
    </script>
    // child.vue
    // 此处忽略template模板的东西
    <script>
    export default {
        name: &#39;child&#39;,
        // inject
        // 第一种
        inject: [ &#39;a&#39;, &#39;b&#39; ]
        // 第二种
        inject: {
            abc: { // 可以指定任意不与data,props冲突的变量名,然后指定是指向provide中的哪个变量
                from: &#39;a&#39;,
                default: &#39;sfd&#39; // 如果默认值不是基本数据类型,那就得改用:default: () => {a:1,b:2}
            },
            b: {
                default: &#39;33&#39;
            }
        }
    }
    </script>

#props:適用相鄰兩個元件的傳值(父->子);$emit: 子->父

正經的props/$emit可太常見了,都是用爛了的,就不用寫範例程式碼了吧。

    只適用於相鄰層級的父子元件之間傳值
  • 對於多層元件的傳值雖然也能用props傳,但是吧,這樣的話會讓程式碼很難維護,極不建議。

eventBus: 地位與vuex差不多,適用任意元件,包容性極強

問題:

    不方便維護:如果在專案裡用的多了,可能出現方法名稱衝突導致異常的問題,而且比較不方便檢驗。
  • 範例:
  • // utils/eventBus.js
    import Vue from &#39;vue&#39;
    const EventBus = new Vue()
    export default EventBus
    // main.js
    // 进行全局挂载
    import eventBus from &#39;@/utils/eventBus&#39;
    Vue.prototype.$eventBos = eventBus
    // views/parent.vue
    <template>
        <div>
            <button @click="test">测试</button>
        </div>
    </template>
    <script>
    export default {
        data() {
            return {}
        },
        methods: {
            test() {
                this.$eventBus.$emit(&#39;testBus&#39;, &#39;test&#39;)
            }
        }
    }
    // views/child.vue
    <template>
        <div>
            {{ testContent }} <!-- test -->
        </div>
    </template>
    <script>
    export default {
        data() {
            return {
                testContent: &#39;&#39;
            }
        },
        mounted() {
            this.$eventBus.$on(&#39;test&#39;, e => this.testContent = e)
        }
    }

$attrs / $listeners

    $attrs
    • #官方解釋
        從父元件傳給自訂子元件的屬性,如果沒有 
      • prop 接收會自動設定到子元件內部的最外層標籤上,如果是 class 和 style 的話,會合併最外層標籤的 class 和 style
      • 如果子元件中不想繼承父元件傳入的非 
      • prop 屬性,可以使用 inheritAttrs 停用繼承,然後透過 v-bind="$ attrs" 將外部傳入的非 prop 屬性設為希望的標籤上,但這不會改變 class 和 style
    • 當父元件向子元件傳值,但是子元件並沒有全部將傳過來的值在props中宣告時,在子元件裡就可以透過
    • $attrs來代理程式取得所有父元件傳過來的值。
    • 範例:這是父元件

vue中不同情況怎麼進行通訊?方式分享

    這是子元件: 沒有宣告props

    vue中不同情況怎麼進行通訊?方式分享

    #這是dom展示:

    vue中不同情況怎麼進行通訊?方式分享

    ######
    • 此时,通过dom可以发现,所有没有声明的信息,全部出现在了子组件的根元素上。
    • 如果要让没有声明的信息不出现在子组件的根元素上,那就在子组件与data同级的位置加个属性:inheritAttrs: false;这样就不会未通过props接收的变量就不会出现在子组件的根元素上了
    • 至于怎么传递给子组件的子组件的子组件的子组件....等,那就需要给子组件的子组件依次都绑定:v-bind="$attrs"即可。
    • 注意这样只适用于传递数据。
  • $listeners
    • 官方解释:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用
    • 当父组件向子组件传递回调时,子组件可以通过$listeners代理所有回调。
    • 示例:这是父组件

vue中不同情況怎麼進行通訊?方式分享

    • 这是子组件

vue中不同情況怎麼進行通訊?方式分享

    • 这是执行展示:

      vue中不同情況怎麼進行通訊?方式分享

    • 同时可以发现子组件加上inheritAttrs:false之后根组件里的未声明props接受的变量消失了

      vue中不同情況怎麼進行通訊?方式分享

  • 最后:建议最好不要用这个玩意,虽然他们都可以相对便捷的将第一级组件的属性,方法回调传递给N级子组件中的任一级,但是之后进行bug定位,或者分析需求将会是一个比较大的挑战。

不同窗口(同浏览器不同页签内)

同浏览器的不同页签之间的通讯,大多数的场景是:项目里的增删改查都是打开的新页面,然后新增结束后就触发列表页重新获取列表。这种场景下有什么方法呢?

监听stroage事件

// 需要监听的页面
mounted() {
    window.addEventListener(&#39;storage&#39;, this.storageEvent);
},
beforeDestroy() {
    window.removeEventListener()
}
methods: {
    storageEvent(e) {
        console.log("storage值发生变化后触发:", e)
    }
}
  • 切记:第一条:要记得将监听的事件在组件销毁之前解除监听。否则会给你惊”喜“
  • 切记:第二条:其中监听方法回调一定要在methods中定义,然后通过this进行引用,否则你在解除事件监听的时候将无效。

不同浏览器

不同浏览器的同一网站的有通讯的必要吗?
如果有那就:websocket(比如聊天室)
哈哈哈哈

(学习视频分享:web前端开发编程入门

以上是vue中不同情況怎麼進行通訊?方式分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除