Vue 跨級通信

vue 組件之間的跨級通信

  1. 概念:Vue2.2.0 新增 API,這對選項須要一塊兒使用,以容許一個祖先組件向其全部子孫後代注入一個依賴,不論組件層次有多深,並在起上下游關係成立的時間裏始終生效。一言而蔽之:祖先組件中經過 provider 來提供變量,而後在子孫組件中經過 inject 來注入變量。 provide / inject API 主要解決了跨級組件間的通訊問題,不過它的使用場景,主要是子組件獲取上級組件的狀態,跨級組件間創建了一種主動提供與依賴注入的關係。

父組件:html

<script>
import Children  from '@/components/children.vue'

export default {
  name: 'home',
  components: {
    Children
  },
   provide(){
        return {
            value:"來自app"
        }
  }
}
複製代碼

子組件(後代組件):vue

<template>
    <div>
       {{value}}
    </div>
</template>

<script>
    export default {
        inject:["value"]
    }
</script>
複製代碼

父組件經過provide將value這個變量提供給它的全部的子組件,而子組件經過inject訪問這個變量。bash

須要注意的是:provide 和 inject 綁定並非可響應的。這是刻意爲之的。然而,若是你傳入了一個可監聽的對象,那麼其對象的屬性仍是可響應的。app

因此父組件的value若是改變了,子組件的value是不會改變的。ide

provide和inject怎麼實現數據響應式:函數

通常來講,有兩種辦法:優化

  • provide 祖先組件的實例,而後在子孫組件中注入依賴,這樣就能夠在子孫組件中直接修改祖先組件的實例的屬性,不過這種方法有個缺點就是這個實例上掛載不少沒有必要的東西好比 props,methods
  • 使用 2.6 最新 API Vue.observable 優化響應式 provide(推薦)
  • 咱們來看個例子:孫組件 D、E 和 F 獲取 A 組件傳遞過來的 color 值,並能實現數據響應式變化,即 A 組件的 color 變化後,組件 D、E、F 不會跟着變(核心代碼以下:)
// A 組件
<div>
      <h1>A 組件</h1>
      <button @click="() => changeColor()">改變color</button>
      <ChildrenB />
      <ChildrenC />
</div>
......
  data() {
    return {
      color: "blue"
    };
  },
  // provide() {
  //   return {
  //     theme: {
  //       color: this.color //這種方式綁定的數據並非可響應的
  //     } // 即A組件的color變化後,組件D、E、F不會跟着變
  //   };
  // },
  provide() {
    return {
      theme: this//方法一:提供祖先組件的實例
    };
  },
  methods: {
    changeColor(color) {
      if (color) {
        this.color = color;
      } else {
        this.color = this.color === "blue" ? "red" : "blue";
      }
    }
  }
  // 方法二:使用2.6最新API Vue.observable 優化響應式 provide
  // provide() {
  //   this.theme = Vue.observable({
  //     color: "blue"
  //   });
  //   return {
  //     theme: this.theme
  //   };
  // },
  // methods: {
  //   changeColor(color) {
  //     if (color) {
  //       this.theme.color = color;
  //     } else {
  //       this.theme.color = this.theme.color === "blue" ? "red" : "blue";
  //     }
  //   }
  // }
複製代碼
// F 組件
<template functional>
  <div class="border2">
    <h3 :style="{ color: injections.theme.color }">F 組件</h3>
  </div>
</template>
<script>
export default {
  inject: {
    theme: {
      //函數式組件取值不同
      default: () => ({})
    }
  }
};
</script>
複製代碼

參考網址:www.cnblogs.com/fundebug/p/…ui