国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
observable
autorun
computed
更多!
首頁(yè) web前端 js教程 如何使用MOBX管理JavaScript應(yīng)用程序狀態(tài)

如何使用MOBX管理JavaScript應(yīng)用程序狀態(tài)

Feb 17, 2025 am 08:57 AM

How to Manage Your JavaScript Application State with MobX

How to Manage Your JavaScript Application State with MobX

本文由Michel Weststrate和Aaron Boyer同行評(píng)審。感謝所有SitePoint的同行評(píng)審員,使SitePoint的內(nèi)容盡善盡美!

如果您曾經(jīng)使用jQuery編寫(xiě)過(guò)比非常簡(jiǎn)單的應(yīng)用程序更複雜的應(yīng)用程序,您可能遇到過(guò)保持UI不同部分同步的問(wèn)題。通常,數(shù)據(jù)的更改需要反映在多個(gè)位置,並且隨著應(yīng)用程序的增長(zhǎng),您可能會(huì)發(fā)現(xiàn)自己陷入困境。為了控制這種混亂,通常使用事件來(lái)讓?xiě)?yīng)用程序的不同部分知道何時(shí)發(fā)生了更改。

那麼,您今天是如何管理應(yīng)用程序狀態(tài)的呢?我要冒昧地說(shuō),您過(guò)度訂閱了更改。沒(méi)錯(cuò)。我什至不認(rèn)識(shí)你,但我就要指出來(lái)。如果您沒(méi)有過(guò)度訂閱,那麼我敢肯定您工作太努力了。

當(dāng)然,除非您使用MobX……

關(guān)鍵要點(diǎn)

  • 利用MobX簡(jiǎn)化狀態(tài)管理:利用MobX通過(guò)可觀察對(duì)像有效地管理應(yīng)用程序狀態(tài),減少在Redux等其他狀態(tài)管理庫(kù)中發(fā)現(xiàn)的複雜性和樣板代碼。
  • MobX自動(dòng)更新:實(shí)現(xiàn)MobX的autorun功能,以自動(dòng)響應(yīng)狀態(tài)更改更新UI組件,無(wú)需手動(dòng)事件處理,從而簡(jiǎn)化整個(gè)應(yīng)用程序的同步過(guò)程。
  • 使用計(jì)算值增強(qiáng)性能:使用MobX的計(jì)算值從狀態(tài)派生數(shù)據(jù),確保僅在必要時(shí)重新渲染組件,從而提高整體應(yīng)用程序性能。
  • MobX易於上手:通過(guò)將標(biāo)準(zhǔn)對(duì)象轉(zhuǎn)換為可觀察對(duì)象,將MobX無(wú)縫集成到現(xiàn)有的JavaScript應(yīng)用程序中,允許逐步採(cǎi)用,而無(wú)需完全重寫(xiě)。
  • 利用MobX操作進(jìn)行事務(wù)性修改:應(yīng)用MobX操作將狀態(tài)修改封裝在事務(wù)中,從而批量更新並最大限度地減少冗餘渲染,從而獲得更高效、更不易出錯(cuò)的代碼。

什麼是“狀態(tài)”?

這是一個(gè)人物。嘿,那就是我!我有一個(gè)firstName、lastName和age。此外,如果我遇到麻煩,fullName()函數(shù)可能會(huì)出現(xiàn)。

var person = {
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 37,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  }
};

您將如何通知您的各種輸出(視圖、服務(wù)器、調(diào)試日誌)對(duì)該人員的修改?您將在何時(shí)觸發(fā)這些通知?在MobX之前,我將使用觸發(fā)自定義jQuery事件或js-signals的setter。這些選項(xiàng)為我提供了良好的服務(wù),但是,我對(duì)它們的用法遠(yuǎn)非細(xì)緻入微。如果person對(duì)象的任何部分發(fā)生更改,我將觸發(fā)一個(gè)“changed”事件。

假設(shè)我有一段視圖代碼顯示我的名字。如果我更改了我的年齡,該視圖將更新,因?yàn)樗c該person的changed事件綁定。

var person = {
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 37,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  }
};

我們?nèi)绾问站o這種過(guò)度觸發(fā)?簡(jiǎn)單。只需為每個(gè)字段設(shè)置一個(gè)setter,並為每個(gè)更改設(shè)置單獨(dú)的事件。等等——如果您想一次更改age和firstName,您可能會(huì)開(kāi)始過(guò)度觸發(fā)。您必須創(chuàng)建一種方法來(lái)延遲事件觸發(fā),直到兩個(gè)更改都完成。這聽(tīng)起來(lái)像工作,而我很懶……

MobX來(lái)救援

MobX是由Michel Weststrate開(kāi)發(fā)的一個(gè)簡(jiǎn)單、專(zhuān)注、高效且不顯眼的狀態(tài)管理庫(kù)。

來(lái)自MobX文檔:

只需對(duì)狀態(tài)執(zhí)行某些操作,MobX將確保您的應(yīng)用程序尊重這些更改。

person.events = {};

person.setData = function (data) {
  $.extend(person, data);
  $(person.events).trigger('changed');
};

$(person.events).on('changed', function () {
  console.log('first name: ' + person.firstName);
});

person.setData({age: 38});

注意到區(qū)別了嗎? mobx.observable是我所做的唯一更改。讓我們?cè)俅尾榭丛?code>console.log示例:

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 37,
  fullName: function () {
    return this.firstName + ' ' + this.lastName;
  }
});

使用autorun,MobX將只觀察已訪問(wèn)的內(nèi)容。

如果您認(rèn)為這很整潔,請(qǐng)查看以下內(nèi)容:

mobx.autorun(function () {
  console.log('first name: ' + person.firstName);
});

person.age = 38; // 打印為空
person.lastName = 'RUBY!'; // 仍然為空
person.firstName = 'Matthew!'; // 此處觸發(fā)

感興趣嗎?我知道你感興趣。

MobX核心概念

observable

mobx.autorun(function () {
  console.log('Full name: ' + person.fullName);
});

person.age = 38; // 打印為空
person.lastName = 'RUBY!'; // 觸發(fā)
person.firstName = 'Matthew!'; // 也觸發(fā)

MobX可觀察對(duì)像只是對(duì)象。在這個(gè)例子中,我沒(méi)有觀察任何東西。此示例顯示瞭如何開(kāi)始將MobX集成到您現(xiàn)有的代碼庫(kù)中。只需使用mobx.observable()mobx.extendObservable()即可開(kāi)始。

autorun

var log = function(data) {
  $('#output').append('' +data+ '');
}

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 34
});

log(person.firstName);

person.firstName = 'Mike';
log(person.firstName);

person.firstName = 'Lissy';
log(person.firstName);

當(dāng)您的可觀察值發(fā)生變化時(shí),您想做些什麼,對(duì)吧?讓我介紹autorun(),它將在任何引用的可觀察值發(fā)生變化時(shí)觸發(fā)回調(diào)。請(qǐng)注意,在上面的示例中,當(dāng)age更改時(shí),autorun()不會(huì)觸發(fā)。

computed

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 0
});

mobx.autorun(function () {
  log(person.firstName + ' ' + person.age);
});

// 這將打印Matt NN 10次
_.times(10, function () {
  person.age = _.random(40);
});

// 這將什么也不打印
_.times(10, function () {
  person.lastName = _.random(40);
});

看到那個(gè)fullName函數(shù)了嗎?注意它沒(méi)有參數(shù)以及get? MobX將自動(dòng)為您創(chuàng)建一個(gè)計(jì)算值。這是我最喜歡的MobX功能之一。注意person.fullName有什麼奇怪的地方嗎?再看一遍。這是一個(gè)函數(shù),您無(wú)需調(diào)用它就可以看到結(jié)果!通常,您將調(diào)用person.fullName()而不是person.fullName。您剛剛遇到了您的第一個(gè)JS getter。

樂(lè)趣並沒(méi)有到此結(jié)束! MobX將監(jiān)視計(jì)算值的依賴(lài)項(xiàng)以進(jìn)行更改,並且在它們發(fā)生更改時(shí)運(yùn)行。如果沒(méi)有任何更改,則將返回緩存的值。請(qǐng)參見(jiàn)下面的情況:

var person = mobx.observable({
  firstName: 'Matt',
  lastName: 'Ruby',
  age: 0,
  get fullName () {
    return this.firstName + ' ' + this.lastName;
  }
});
log(person.fullName);

person.firstName = 'Mike';
log(person.fullName);

person.firstName = 'Lissy';
log(person.fullName);

在這裡您可以看到,我已經(jīng)多次命中了person.fullName計(jì)算,但是函數(shù)運(yùn)行的唯一時(shí)間是當(dāng)firstName或lastName發(fā)生更改時(shí)。這是MobX可以極大地加快應(yīng)用程序速度的方法之一。

更多!

我不會(huì)再繼續(xù)重寫(xiě)MobX精彩的文檔了。查看文檔以了解有關(guān)使用和創(chuàng)建可觀察對(duì)象的更多方法。

(以下內(nèi)容略去部分代碼示例和詳細(xì)解釋?zhuān)A艉诵膬?nèi)容和結(jié)構(gòu))

將MobX投入使用

在過(guò)分枯燥之前,讓我們構(gòu)建一些東西。

這是一個(gè)簡(jiǎn)單的非MobX示例,它將顯示每當(dāng)人員更改時(shí)人員的全名。

注意,即使我們從未更改名字,名稱(chēng)也渲染了10次。您可以使用許多事件或檢查某種更改的有效負(fù)載來(lái)優(yōu)化此問(wèn)題。這工作量太大了。

這是一個(gè)使用MobX構(gòu)建的相同示例:

注意,沒(méi)有事件、觸發(fā)器或on。使用MobX,您正在處理最新值以及它已更改的事實(shí)。注意它只渲染了一次嗎?這是因?yàn)槲覜](méi)有更改autorun正在監(jiān)視的任何內(nèi)容。

讓我們構(gòu)建一些稍微不那麼瑣碎的東西:

在這裡,我們能夠編輯整個(gè)person對(duì)象並自動(dòng)監(jiān)視數(shù)據(jù)輸出?,F(xiàn)在,此示例中有一些軟點(diǎn),最值得注意的是輸入值與person對(duì)像不同步。讓我們解決這個(gè)問(wèn)題:

我知道,你還有一個(gè)抱怨:“Ruby,你渲染過(guò)度了!”你是對(duì)的。這就是為什麼許多人選擇使用React的原因。 React允許您輕鬆地將輸出分解成可以單獨(dú)渲染的小組件。

為了完整起見(jiàn),這裡有一個(gè)我已優(yōu)化的jQuery示例。

我會(huì)在真實(shí)的應(yīng)用程序中做這樣的事情嗎?可能不會(huì)。如果我需要這種粒度,我隨時(shí)都會(huì)使用React。當(dāng)我在真實(shí)的應(yīng)用程序中使用MobX和jQuery時(shí),我使用足夠細(xì)緻的autorun(),以至於我沒(méi)有在每次更改時(shí)都重建整個(gè)DOM。

您已經(jīng)走到了這一步,所以這裡是用React和MobX構(gòu)建的相同示例

讓我們構(gòu)建一個(gè)幻燈片放映

您將如何表示幻燈片放映的狀態(tài)?讓我們從單個(gè)幻燈片工廠開(kāi)始:

我們應(yīng)該有一些東西可以聚合我們所有的幻燈片。讓我們現(xiàn)在構(gòu)建它:

幻燈片放映開(kāi)始了!這更有趣,因?yàn)槲覀冇幸粋€(gè)可觀察的幻燈片數(shù)組,它允許我們從集合中添加和刪除幻燈片,並相應(yīng)地更新我們的UI。接下來(lái),我們添加activeSlide計(jì)算值,該值將根據(jù)需要保持自身最新。

讓我們渲染我們的幻燈片放映。我們還沒(méi)有準(zhǔn)備好HTML輸出,所以我們只會(huì)打印到控制臺(tái)。

很酷,我們有一些幻燈片,autorun剛剛打印出了它們當(dāng)前的狀態(tài)。讓我們更改一個(gè)或兩個(gè)幻燈片:

看起來(lái)我們的autorun正在工作。如果您更改autorun正在監(jiān)視的任何內(nèi)容,它將觸發(fā)。讓我們將輸出派生從控制臺(tái)更改為HTML:

我們現(xiàn)在已經(jīng)有了這個(gè)幻燈片放映的基本顯示,但是,還沒(méi)有交互性。您不能點(diǎn)擊縮略圖並更改主圖像。但是,您可以輕鬆地使用控制臺(tái)更改圖像文本並添加幻燈片:

讓我們創(chuàng)建我們的第一個(gè)也是唯一一個(gè)操作來(lái)設(shè)置選定的幻燈片。我們將不得不通過(guò)添加以下操作來(lái)修改slideShowModelFactory

您可能會(huì)問(wèn),為什麼要使用操作?好問(wèn)題! MobX操作不是必需的,正如我在更改可觀察值的其他示例中所展示的那樣。

操作在幾個(gè)方面對(duì)您有所幫助。首先,所有MobX操作都在事務(wù)中運(yùn)行。這意味著我們的autorun和其他MobX反應(yīng)將等待操作完成後再觸發(fā)。考慮一下。如果我嘗試在事務(wù)之外停用活動(dòng)幻燈片並激活下一個(gè)幻燈片會(huì)發(fā)生什麼?我們的autorun將觸發(fā)兩次。第一次運(yùn)行會(huì)很尷尬,因?yàn)閷](méi)有活動(dòng)幻燈片可供顯示。

除了它們的事務(wù)性質(zhì)之外,MobX操作往往使調(diào)試更簡(jiǎn)單。我傳遞給mobx.action的第一個(gè)可選參數(shù)是字符串“set active slide”。此字符串可以使用MobX的調(diào)試API輸出。

所以我們有我們的操作,讓我們使用jQuery連接它的用法:

就是這樣。您現(xiàn)在可以點(diǎn)擊縮略圖,並且活動(dòng)狀態(tài)將按預(yù)期傳播。這是幻燈片放映的工作示例:

這是一個(gè)使用React的相同幻燈片放映的示例。

注意,我根本沒(méi)有更改模型?就MobX而言,React只是您數(shù)據(jù)的另一種派生,例如jQuery或控制臺(tái)。

jQuery幻燈片放映示例的警告

請(qǐng)注意,我沒(méi)有以任何方式優(yōu)化jQuery示例。我們?cè)诿看胃臅r(shí)都會(huì)破壞整個(gè)幻燈片放映DOM。通過(guò)破壞,我的意思是我們?cè)诿看吸c(diǎn)擊時(shí)都會(huì)替換幻燈片放映的所有HTML。如果您要構(gòu)建一個(gè)強(qiáng)大的基於jQuery的幻燈片放映,您可能會(huì)在初始渲染後調(diào)整DOM,方法是設(shè)置和刪除活動(dòng)類(lèi)並更改mainImagesrc屬性。

想了解更多?

如果您想了解更多關(guān)於MobX的信息,請(qǐng)查看下面一些其他有用的資源:

如果您有任何疑問(wèn),請(qǐng)?jiān)谙旅娴脑u(píng)論中告訴我,或者在MobX gitter頻道中找到我。

關(guān)於使用MobX管理JavaScript應(yīng)用程序狀態(tài)的常見(jiàn)問(wèn)題解答(FAQ)

(以下內(nèi)容略去FAQ部分,因?yàn)槠^(guò)長(zhǎng),且與核心內(nèi)容關(guān)係不大。)

以上是如何使用MOBX管理JavaScript應(yīng)用程序狀態(tài)的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

熱門(mén)話題

Java vs. JavaScript:清除混亂 Java vs. JavaScript:清除混亂 Jun 20, 2025 am 12:27 AM

Java和JavaScript是不同的編程語(yǔ)言,各自適用於不同的應(yīng)用場(chǎng)景。 Java用於大型企業(yè)和移動(dòng)應(yīng)用開(kāi)發(fā),而JavaScript主要用於網(wǎng)頁(yè)開(kāi)發(fā)。

JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 JavaScript評(píng)論:簡(jiǎn)短說(shuō)明 Jun 19, 2025 am 12:40 AM

JavascriptconcommentsenceenceEncorenceEnterential gransimenting,reading and guidingCodeeXecution.1)單inecommentsareusedforquickexplanations.2)多l(xiāng)inecommentsexplaincomplexlogicorprovideDocumentation.3)

如何在JS中與日期和時(shí)間合作? 如何在JS中與日期和時(shí)間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對(duì)像有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開(kāi)始;3.手動(dòng)格式化日期需拼接字符串,也可使用第三方庫(kù);4.處理時(shí)區(qū)問(wèn)題建議使用支持時(shí)區(qū)的庫(kù),如Luxon。掌握這些要點(diǎn)能有效避免常見(jiàn)錯(cuò)誤。

為什麼要將標(biāo)籤放在的底部? 為什麼要將標(biāo)籤放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

JavaScript與Java:開(kāi)發(fā)人員的全面比較 JavaScript與Java:開(kāi)發(fā)人員的全面比較 Jun 20, 2025 am 12:21 AM

JavaScriptIspreferredforredforwebdevelverment,而Javaisbetterforlarge-ScalebackendsystystemsandSandAndRoidApps.1)JavascriptexcelcelsincreatingInteractiveWebexperienceswebexperienceswithitswithitsdynamicnnamicnnamicnnamicnnamicnemicnemicnemicnemicnemicnemicnemicnemicnddommanipulation.2)

什麼是在DOM中冒泡和捕獲的事件? 什麼是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個(gè)階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。 1.事件捕獲通過(guò)addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委託,提高動(dòng)態(tài)內(nèi)容處理效率;5.捕獲可用於提前攔截事件,如日誌記錄或錯(cuò)誤處理。了解這兩個(gè)階段有助於精確控制JavaScript響應(yīng)用戶(hù)操作的時(shí)機(jī)和方式。

JavaScript:探索用於高效編碼的數(shù)據(jù)類(lèi)型 JavaScript:探索用於高效編碼的數(shù)據(jù)類(lèi)型 Jun 20, 2025 am 12:46 AM

javascripthassevenfundaMentalDatatypes:數(shù)字,弦,布爾值,未定義,null,object和symbol.1)numberSeadUble-eaduble-ecisionFormat,forwidevaluerangesbutbecautious.2)

如何減少JavaScript應(yīng)用程序的有效載荷大?。? />
								</a>
								<a href=如何減少JavaScript應(yīng)用程序的有效載荷大??? Jun 26, 2025 am 12:54 AM

如果JavaScript應(yīng)用加載慢、性能差,問(wèn)題往往出在payload太大,解決方法包括:1.使用代碼拆分(CodeSplitting),通過(guò)React.lazy()或構(gòu)建工具將大bundle拆分為多個(gè)小文件,按需加載以減少首次下載量;2.移除未使用的代碼(TreeShaking),利用ES6模塊機(jī)制清除“死代碼”,確保引入的庫(kù)支持該特性;3.壓縮和合併資源文件,啟用Gzip/Brotli和Terser壓縮JS,合理合併文件並優(yōu)化靜態(tài)資源;4.替換重型依賴(lài),選用輕量級(jí)庫(kù)如day.js、fetch

See all articles