欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

一文搞懂vue中provide和inject實(shí)現(xiàn)原理對(duì)抗平庸

 更新時(shí)間:2023年04月16日 12:02:00   作者:陪我去看海  
這篇文章主要為大家介紹了vue中provide和inject實(shí)現(xiàn)原理的深入理解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在沒(méi)有面試又似乎馬上就會(huì)有面試的躁動(dòng)不安的日子里,迷迷糊糊的看到一個(gè)面試題“你知道provide和inject的實(shí)現(xiàn)原理嗎”,我學(xué)著面試官的樣子試問(wèn)自己"你知道嗎",我的大腦翻遍了記憶,也沒(méi)有找到,可能是沒(méi)有記載,亦可能是時(shí)間過(guò)長(zhǎng)被積壓在了記憶深處,我始終沒(méi)有回答我自己,這讓我非常懊惱,又滿是無(wú)奈。所以我想搞懂它,用它的原理來(lái)?yè)崞轿业膬?nèi)心。

provide & inject 的用法

provide("num", 0);
const num = inject("num")

這大致就是它們的美貌,它們示人的一面,如此優(yōu)雅,如此簡(jiǎn)潔。它們隱藏了內(nèi)心,從這里讓我無(wú)法了解到它的內(nèi)心它到底在想什么呢,在做什么呢,我嘗試著與它親近,逐漸發(fā)現(xiàn)它的有趣。

在provide中,它留了兩個(gè)深入了解它的窗口provide(key, value),同樣在inject中,目前只能看到一個(gè)inject(key),結(jié)合它們的功能知道,它們的主要功能不就是存和取,所以想要了解它們就要搞清楚如何存,怎么取,先讓這疑問(wèn)留在心底罷,來(lái)看看"下面例子"

下面例子

有這樣一串代碼,讓我們實(shí)現(xiàn)provide 和 inject這兩個(gè)函數(shù),達(dá)到在foo對(duì)象中的fooObj取的是app對(duì)象中provide提供的對(duì)象obj,我們?nèi)绾螌?shí)現(xiàn)

const obj = { name: "app" };
const foo = {
  name: "foo",
  provides: {},
  parent: null,
  setup() {
    foo.parent = app; // 先忽略
    const fooObj = inject("obj");
    console.log("app -> foo: obj ", fooObj === obj); // 要求打印true
  },
  children: null,
};
const app = {
  name: "app",
  provides: {},
  parent: null,
  setup() {
    app.parent = app; // 先忽略
    provide("obj", obj);
  },
  children: foo,
};
(function () {
  app.setup();
  foo.setup();
})();

需要實(shí)現(xiàn)什么

首先我們需要明確我們要干什么:

  • 其實(shí)本質(zhì)就是要實(shí)現(xiàn)provide和inject函數(shù)
  • 明確代碼在做什么
  • 有兩個(gè)對(duì)象app 和 foo,它兩長(zhǎng)得一樣美麗,初始化階段,它兩內(nèi)部的setup方法會(huì)依次執(zhí)行,在內(nèi)部它們分別使用了provide提供數(shù)據(jù),以及使用inject獲取數(shù)據(jù),要求fooObj === obj為true,這其實(shí)就是判斷是否是同一個(gè)數(shù)據(jù)的根本方法。

知道了這些后,我們一起來(lái)認(rèn)識(shí)一下provide和inject吧,我們以主觀意識(shí)去了解它們,把我認(rèn)為它是什么樣子畫(huà)出來(lái)。

首先畫(huà)出它的骨架:

function provide(key, value) {
    // 靈魂深處
}
function inject(key) {
    // 靈魂深處
}

我們要一起探聽(tīng)我們理想中它們的靈魂

內(nèi)心中的呈現(xiàn)

provide分析

  • 提供了key-value
  • 我們需要存儲(chǔ)在各自對(duì)象中的provides屬性中
function provide(key, value) {
  // 獲取當(dāng)前提供provide的對(duì)象
  const currentInstance = app;
  // 將provide提供的key-value存儲(chǔ)到當(dāng)前對(duì)象的provides中
  let { provides } = currentInstance;
  provides[key] = value;
}

inject分析

  • 從parent下的provides開(kāi)始取值,因?yàn)樵谧约哼@里提供的provide不需要進(jìn)行inject,多此一舉
function inject(key) {
  const currentInstance = foo;
  // 從parent的provides取值
  const parentProvides = currentInstance.parent.provides;
  // 如果提供了值,就可以取到并返回
  if (key in parentProvides) {
    return parentProvides[key];
  }
}

這時(shí)候我們可以打印出(fooObj === obj) === true了

在沉浸喜悅的同時(shí),在provide和inject靈魂處蹦出字來(lái)你還是不夠了解我,我仔細(xì)思考,好像也是,它們還有一個(gè)特性就是跨層級(jí),這恰恰是遺忘了它最有靈魂的地方,所以我們重新規(guī)劃下面例子

下面例子

const obj = { name: "app" };
const baz = {
  name: "foo",
  provides: {},
  parent: null,
  setup() {
    baz.parent = foo;
    const bazObj = inject("obj");
    console.log("app -> baz: obj ", bazObj === obj); // 要求打印true
  },
  children: null,
};
const foo = {
  name: "foo",
  provides: {},
  parent: null,
  setup() {
    foo.parent = app;
  },
  children: baz,
};
const app = {
  name: "app",
  provides: {},
  parent: null,
  setup() {
    app.parent = app;
    provide("obj", obj);
  },
  children: foo,
};
(function () {
  app.setup();
  foo.setup();
  baz.setup();
})();

這時(shí)候就會(huì)打印false了PS: 如果你還是true,那是因?yàn)槟阍?inject 里 currentInstance沒(méi)有改變,這里是需要改變的,只能指到當(dāng)前對(duì)象,所以我們?nèi)绾谓鉀Q呢?

這里說(shuō)到如果currentInstance 是 foo,那就沒(méi)有問(wèn)題,但是又因?yàn)檫@里是只能指向當(dāng)前對(duì)象的,所以不能直接賦值,突然,靈光一閃,無(wú)非不就是查找的時(shí)候需要繼續(xù)向下查找,這不是和原型鏈一樣嘛內(nèi)心:哈哈哈,我真聰明,所以我們給它進(jìn)行原型連接不就好了,讓一直向parent上找,直到找不到。

跨層級(jí)查找

進(jìn)行原型連接,實(shí)現(xiàn)跨層級(jí):Object.create(obj): 創(chuàng)造一個(gè)原型為obj的空對(duì)象

const foo = {
  name: "foo",
  provides: {},
  parent: null,
  setup() {
    foo.parent = app;
    // 執(zhí)行原型連接
    foo.provides = Object.create(foo.parent.provides);
  },
  children: baz,
};

這樣就又打印true了,因?yàn)樗苯釉趂oo.provides上查找,無(wú)法找到提供的obj所以會(huì)undefined,原型連接后,查找會(huì)順著原型鏈查找,直到找不到,那找不到的時(shí)候怎么辦呢,它會(huì)報(bào)錯(cuò)的呀,這是不能容忍的,所以inject向我敞開(kāi)心扉,和我聊自己是怎么樣的一個(gè)API,它說(shuō):"我其實(shí)有三種外貌,對(duì)應(yīng)不同心情,分別是inject(key)、inject(key, defaultValue)和 defaultValue 可以是函數(shù)",至此我們之間的關(guān)系好像又進(jìn)一步,我好像更了解它們了。

inject放下偽裝,吐露心聲

inject 的形態(tài):

  • inject(key) —— 已實(shí)現(xiàn)
  • inject(key, defaultValue) —— 未實(shí)現(xiàn)
  • inject(key, () => defaultValue) —— 未實(shí)現(xiàn)

回顧一下inject:

function inject(key) {
  const currentInstance = baz;
  const parentProvides = currentInstance.parent.provides;
  if (key in parentProvides) {
    return parentProvides[key];
  }
}

這是我們最后實(shí)現(xiàn)inject的樣子,這會(huì)inject告訴了我們其他狀態(tài),所以我們需要和它更進(jìn)一步,它會(huì)提供一個(gè)defaultValue屬性,所以我們?cè)趐arent鏈中沒(méi)有找到key的時(shí)候,就需要賦值defaultValue了

function inject(key, defaultValue) {
  const currentInstance = baz;
  const parentProvides = currentInstance.parent.provides;
  // 當(dāng)沒(méi)有在 parent 鏈中找到對(duì)應(yīng)key,就返回默認(rèn)值
  if (key in parentProvides) {
    return parentProvides[key];
  } else if (defaultValue) {
    return defaultValue;
  }
}

將baz對(duì)象修改為:

const baz = {
  name: "foo",
  provides: {},
  parent: null,
  setup() {
    baz.parent = foo;
    const defaultBaz = inject("baz", "我是默認(rèn)值啦!");
    console.log(defaultBaz, "baz");
  },
  children: null,
};

打印出了:我是默認(rèn)值啦!

但是當(dāng)defaultValue是回調(diào)函數(shù)的時(shí)候,我們所以需要添加判斷條件,如果是回調(diào)函數(shù),那就直接執(zhí)行。

修改后的inject:

function inject(key, defaultValue) {
  const currentInstance = baz;
  const parentProvides = currentInstance.parent.provides;
  if (key in parentProvides) {
    return parentProvides[key];
  } else if (defaultValue) {
    // 新增判斷
    if (typeof defaultValue === "function") {
      return defaultValue();
    }
    return defaultValue;
  }
}

修改后的baz中的inject使用:

const defaultBaz = inject("baz", () => "我是默認(rèn)值啦!");

同樣也會(huì)打印出:我是默認(rèn)值啦!

現(xiàn)在我們好像成為好朋友了,所以,你好,provide!你好,inject!你們好,各位大帥b!

總結(jié)

  • 每個(gè)provide提供的數(shù)據(jù)都存在當(dāng)前組件的provides屬性上
  • inject取值的時(shí)候,會(huì)從當(dāng)前的父組件中的provides開(kāi)始取值
  • 其實(shí)已經(jīng)懂了 provide 和 inject 原理了,因?yàn)樵赩ue中,他的每個(gè)組件也會(huì)生成組件實(shí)例,而這些屬性全都在實(shí)例對(duì)象上。

以上就是一文搞懂vue中provide和inject實(shí)現(xiàn)原理對(duì)抗平庸的詳細(xì)內(nèi)容,更多關(guān)于vue provide inject實(shí)現(xiàn)原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論