中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue中如何實現非父子組件的通信

發布時間:2022-02-14 14:39:04 來源:億速云 閱讀:284 作者:小新 欄目:開發技術

這篇文章主要介紹了vue中如何實現非父子組件的通信,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

一、Provide和Inject

ProvideInject用于非父子組件之間共享數據,比如有一些深度嵌套的組件,子組件想要獲取父組件的數據,如果不存在Provide和Inject選項,我們可以通過props進行一次傳遞數據,但是這樣做太過于繁瑣。

對于上述情況,我們可以使用ProvideInject無論組件結構嵌套有多深,父組件都可以作為子組件數據的提供者。

父組件存在Provide來提供數據。

子組件存在Inject來獲取數據。

在實際過程中,父組件不知道哪個子組件使用其數據,子組件也不知道使用的是哪個父組件的數據。

Provide和Inject的基本使用

//父組件
<template>
  <div>
    <Content></Content>
  </div>
</template>
<script>
import Content from "./components/Content.vue";
export default {
  data() {
    return {};
  },
  provide:{
    name:"張三",
    age:20
  },
  components: {
    Content
  }
};
</script>
<style scoped></style>
//子組件
<template>
  <div>
    <h2>這里是Content組件</h2>
    <h2>{{ name }} -- {{age}}</h2>
    <ContentBase></ContentBase>
  </div>
</template>
<script>
import ContentBase from "./ContentBase.vue";
export default {
  data() {
    return {};
  },
  components: {
    ContentBase
  },
  inject:["name", "age"]
};
</script>
<style scoped></style>
//孫組件
<template>
  <div>
      <h2>這里是contentBase組件</h2>
      <h2>{{name}} -- {{age}}</h2>
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  inject: ["name", "age"]
};
</script>
<style scoped>
</style>

最終顯示結果為:

vue中如何實現非父子組件的通信

二、Provide和Inject的另一種寫法

我們思考一種情況,如果Provide拿到的數據,是從data拿到的數據,此時如果獲取? 此時this可以使用嗎?

<template>
  <div>
    <Content></Content>
  </div>
</template>
<script>
import Content from "./components/Content.vue";
export default {
  data() {
    return {
      source: ["111","222", "333"]
    };
  },
  provide:{
    name:"張三",
    age:20,
    res: this.source.length   //我們在此時增加res,想要通過this.source.length拿到數組的長度
  },
  components: {
    Content
  }
};
</script>
<style scoped></style>

該結果是錯誤的。

vue中如何實現非父子組件的通信

報錯信息顯示,我們從undefined上讀取屬性,此時this為undefined。原因:從上面代碼我們可以看出,this指向的是undefiend(因為this執行最外層)。

解決方法

我們將Provide設置為一個函數,并且返回一個對象,如下代碼所示:

<template>
  <div>
    <Content></Content>
  </div>
</template>
<script>
import Content from "./components/Content.vue";
export default {
  data() {
    return {
      source: ["111", "222", "333"],
    };
  },
  provide() {
    return {
      name: "張三",
      age: 20,
      res: this.source.length,
    };
  },
  components: {
    Content,
  },
};
</script>
<style scoped></style>

顯示結果:

vue中如何實現非父子組件的通信

此時我們再思考一個問題,如果我們向data數組中新增一個元素,在其他地方獲取的數組長度會跟隨變化嗎?

<template>
  <div>
    <Content></Content>
    <button @click="addOneItem">點擊</button>
  </div>
</template>
<script>
import Content from "./components/Content.vue";
export default {
  data() {
    return {
      source: ["111", "222", "333"],
    };
  },
  provide() {
    return {
      name: "張三",
      age: 20,
      res: this.source.length,
    };
  },
  components: {
    Content,
  },
  methods:{  //在這里添加點擊事件
    addOneItem() {
      this.source.push("nnn")
      console.log(this.source)
    }
  }
};
</script>
<style scoped></style>

vue中如何實現非父子組件的通信

vue中如何實現非父子組件的通信

結果如上圖所示,可以看到數據是被添加進去的,但是子組件并沒有檢測到數據的變化。

此時我們可以使用computed來檢測this.source.length的變化,使用代碼如下所示。

<template>
  <div>
    <Content></Content>
    <button @click="addOneItem">點擊</button>
  </div>
</template>
<script>
import Content from "./components/Content.vue";
import { computed } from "vue"   //從vue中引入computed
export default {
  data() {
    return {
      source: ["111", "222", "333"],
    };
  },
  provide() {
    return {
      name: "張三",
      age: 20,
      res: computed(() => this.source.length), //在這里添加computed
    };
  },
  components: {
    Content,
  },
  methods:{
    addOneItem() {
      this.source.push("nnn")
      console.log(this.source)
    }
  }
};
</script>
<style scoped></style>

vue中如何實現非父子組件的通信

vue中如何實現非父子組件的通信

因為我們通過computed獲取的是一個對象,此時我們通過value屬性拿到值。

三、全局事件總線mitt庫

在vue2時,如果我們使用事件總線可以使用this.$bus = new Vue()也就是實例化一個vue對象。但是我們在vue3中不能這樣用。所以我們采用第三方庫來實現組件之間的通信。這個第三方庫為mitt

一、安裝

npm install mitt

在文件中引入并且進行初始化導出。

import mitt from "mitt";
const emitter = new mitt()
export default emitter

監聽事件,第一個參數是事件名,第二個參數是回調函數。

    emitter.on("why", (data) => {
      console.log(data)
    })
    //*表示可以監聽全部的事件。
    emitter.on("*", (type, data) => {
      console.log(type, data)
    })

vue中如何實現非父子組件的通信

取消事件

//取消emitter中所有的監聽
emitter.all.clear()
//或者
//定義一個函數
function onFoo(){}
emitter.on("foo", onFoo)
emitter.on("foo", onFoo)

感謝你能夠認真閱讀完這篇文章,希望小編分享的“vue中如何實現非父子組件的通信”這篇文章對大家有幫助,同時也希望大家多多支持億速云,關注億速云行業資訊頻道,更多相關知識等著你來學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

锡林浩特市| 那曲县| 乡宁县| 宁陕县| 西和县| 绥阳县| 安福县| 克拉玛依市| 仲巴县| 安达市| 沙田区| 侯马市| 龙州县| 兴隆县| 仙游县| 察雅县| 东丽区| 辽中县| 洪泽县| 黎川县| 株洲市| 合山市| 揭西县| 富宁县| 邻水| 田东县| 高台县| 万山特区| 德令哈市| 突泉县| 车致| 离岛区| 上饶市| 吉林市| 沂南县| 安国市| 衡东县| 丰台区| 繁昌县| 淳化县| 新闻|