日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

來自 Rust 生態(tài)的強(qiáng)烈沖擊?談?wù)?Leptos 在語法設(shè)計上的精妙之處

來源: 責(zé)編: 時間:2024-05-24 17:25:15 218觀看
導(dǎo)讀過去很長一段時間,前端框架們都在往響應(yīng)式的方向發(fā)展。大家都在基于 signal 實(shí)現(xiàn)自己的底層。這種趨勢看上去非常火熱,給人一種前端框架不往這個方向發(fā)展就落后了一樣。同時又由于 React hooks 的深遠(yuǎn)影響,函數(shù)式 + 響應(yīng)

B0F28資訊網(wǎng)——每日最新資訊28at.com

過去很長一段時間,前端框架們都在往響應(yīng)式的方向發(fā)展。大家都在基于 signal 實(shí)現(xiàn)自己的底層。這種趨勢看上去非常火熱,給人一種前端框架不往這個方向發(fā)展就落后了一樣。B0F28資訊網(wǎng)——每日最新資訊28at.com

同時又由于 React hooks 的深遠(yuǎn)影響,函數(shù)式 + 響應(yīng)式成為了不少前端心中最理想的前端框架模樣。Solid 成為了這種模式里最具代表性的框架。B0F28資訊網(wǎng)——每日最新資訊28at.com

但是,盡管如此,我依然對他保持一種不太愿意接納的態(tài)度,并不是說我對 solid 不熟悉,或者抗拒接受新的知識,其根本原因,還是在語法設(shè)計上的問題。B0F28資訊網(wǎng)——每日最新資訊28at.com

基于響應(yīng)式能實(shí)現(xiàn)細(xì)粒度更新,拋去虛擬 DOM 的 diff 成本,性能能夠得到很大的提升。這種設(shè)想其實(shí)非常美好,但是,在語法設(shè)計上會面臨巨大的挑戰(zhàn)。B0F28資訊網(wǎng)——每日最新資訊28at.com

一、Solid.js

我們來觀察并分析一下 solid.js 在語法設(shè)計上存在的問題。B0F28資訊網(wǎng)——每日最新資訊28at.com

function Counter() {  const [count, setCount] = createSignal(0)  return <div onClick={() => setCount(count() + 1)}>    Count: {count()}  </div>}

在這個案例中,我們可以使用 createSignal 創(chuàng)建一個響應(yīng)式數(shù)據(jù)。這里的問題就在于,返回的響應(yīng)式數(shù)據(jù) count 他不是一個數(shù)據(jù),而是一個獲取數(shù)據(jù)的 getter 方法。B0F28資訊網(wǎng)——每日最新資訊28at.com

因?yàn)榈讓踊?Proxy 來實(shí)現(xiàn),我們需要監(jiān)聽到數(shù)據(jù)的變化,那么就需要借助 Proxy 中的 getter 方法來實(shí)現(xiàn),因此反饋到語法上,count 就只能是一個函數(shù)。B0F28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我們想要將其渲染到 JSX 中時,在 solid 中就將其設(shè)計成 {count()}。這里設(shè)計成 count() 是沿用了 React 對于 JSX 的理解,想要傳入一個值給 JSX。B0F28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我們在點(diǎn)擊事件中使用該響應(yīng)式數(shù)據(jù)時。B0F28資訊網(wǎng)——每日最新資訊28at.com

setCount(count() + 1);

如果你要精準(zhǔn)理解 count(),那么理解成本就有點(diǎn)高了,這里的 count() 執(zhí)行,表達(dá)了兩層含義。B0F28資訊網(wǎng)——每日最新資訊28at.com

初始化時,count() 表示會隱式的收集依賴。在跟蹤范圍內(nèi),調(diào)用 getter 會導(dǎo)致調(diào)用 getter 的函數(shù)依賴于對應(yīng)的 signal。當(dāng) signal 更新時,這些依賴都會被重新執(zhí)行。B0F28資訊網(wǎng)——每日最新資訊28at.com

更新時是依賴重新執(zhí)行,不只是 count() 重新執(zhí)行。許多人理解成 count 重新執(zhí)行,那么在語義上會有更進(jìn)一步的沖突。B0F28資訊網(wǎng)——每日最新資訊28at.com

例如:B0F28資訊網(wǎng)——每日最新資訊28at.com

const double_count = () => count() * 2// 或者在 jsx 中<div>count: {count()}</div>

更新時,當(dāng)我們通過點(diǎn)擊等行為觸發(fā)更新,此時當(dāng)我們使用 count(),則只是簡單的計算出 count 當(dāng)前的值。B0F28資訊網(wǎng)——每日最新資訊28at.com

setCount(count() + 1);

這里其實(shí)就是語法設(shè)計上的沖突問題。同樣的函數(shù)執(zhí)行,由于編譯手段的強(qiáng)勢侵入,在不同的場景里表達(dá)了不同的含義。B0F28資訊網(wǎng)——每日最新資訊28at.com

其實(shí) solid.js 的開發(fā)團(tuán)隊(duì)也希望 count 就像是直觀表達(dá)的那樣,他不是一個 getter,而就是直接是一個值,因此就有類似于如下的語法設(shè)計B0F28資訊網(wǎng)——每日最新資訊28at.com

// 這個時候就變得正常了setCount((count) => count + 1);

但是很顯然,如果直接完全像 React 那樣符合直覺的語法設(shè)計,響應(yīng)式的能力就得不到保證了。因此這是擁抱響應(yīng)式不得不做出的犧牲。B0F28資訊網(wǎng)——每日最新資訊28at.com

Solid 的這個語法割裂,在組件傳參的語法設(shè)計中,表現(xiàn)得尤為明顯。B0F28資訊網(wǎng)——每日最新資訊28at.com

例如你看下面這段代碼,令人意外的是,props.msg 是可以具備響應(yīng)性的,當(dāng)我還不熟悉 Solid 的時候直接大吃一驚。B0F28資訊網(wǎng)——每日最新資訊28at.com

function Message(props: Props) {  return <div>    <h1>      hello, this message is: {props.msg}    </h1>    <Child />  </div>}

這是擁抱響應(yīng)式的無奈之舉。因?yàn)樵诮M件傳參的時候,其實(shí)可能存在兩種類型,一種類型是普通數(shù)據(jù),例如:B0F28資訊網(wǎng)——每日最新資訊28at.com

<Message msg='hello world' />

而另外一種,就是響應(yīng)性數(shù)據(jù),例如:B0F28資訊網(wǎng)——每日最新資訊28at.com

<Message msg={msg()} />

如果我希望一個字段,他可以傳普通類型、也可以傳響應(yīng)性類型,那么問題就來了,子元素內(nèi)部如何判斷父組件到底會傳什么類型過來呢?B0F28資訊網(wǎng)——每日最新資訊28at.com

solid 的解決方案就是,只允許在父組件傳參時,這樣寫 {msg()}。下面這種寫法就會報錯。B0F28資訊網(wǎng)——每日最新資訊28at.com

<Message msg={msg} />

B0F28資訊網(wǎng)——每日最新資訊28at.com

這樣做的好處就是 solid 可以利用編譯手段去識別 msg() 然后深入子組件內(nèi)部做依賴收集,從而讓子組件內(nèi)部不需要做額外的判斷。但是付出的代價就是語法割裂更嚴(yán)重了。B0F28資訊網(wǎng)——每日最新資訊28at.com

除此之外,正因?yàn)橛泻诳萍嫉膹?qiáng)勢侵入,因此 solid 中的 JSX 與 React 中的 JSX 表現(xiàn)并完全不一致,也不能按照常規(guī)的表達(dá)式去理解。B0F28資訊網(wǎng)——每日最新資訊28at.com

語法的割裂是我不愿意擁抱 Solid 的主要原因。B0F28資訊網(wǎng)——每日最新資訊28at.com

二、Leptos

讓我們來看看 rust 生態(tài)中,同樣是基于 signal 來實(shí)現(xiàn)的響應(yīng)式框架 Leptos 是如何在語法設(shè)計上解決 solid 的割裂問題的。B0F28資訊網(wǎng)——每日最新資訊28at.com

首先,一個非常巧妙的設(shè)計就是,在 rsx 中,狀態(tài)傳入的括號中,直接接收的就是一個函數(shù)B0F28資訊網(wǎng)——每日最新資訊28at.com

#[component]fn App() -> impl IntoView {  let (count, set_count) = create_signal(0);  view! {    <div>{count}</div>  })

這里類似于 React 的 render propsB0F28資訊網(wǎng)——每日最新資訊28at.com

這樣看著就非常的舒服。因?yàn)槁暶鞯?count 是一個函數(shù),模板渲染中需要的也是一個函數(shù),語法表現(xiàn)就很一致,按照這個設(shè)計,我們就可以不用寫 count() 了。B0F28資訊網(wǎng)——每日最新資訊28at.com

這個小的語法設(shè)計細(xì)節(jié)的調(diào)整,讓整個語法都變得更加一致。B0F28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我們更新時B0F28資訊網(wǎng)——每日最新資訊28at.com

set_count.update(|count| *count += 1)

當(dāng)我們要往子組件中傳遞參數(shù)時B0F28資訊網(wǎng)——每日最新資訊28at.com

<ProgressBar progress=count />

當(dāng)語法規(guī)則發(fā)生一些簡單的調(diào)整,我們會發(fā)現(xiàn),在大多數(shù)情況下,count 的使用都保持了一致性,而不是像 solid 那樣在不同的場景之下有不同的行為。B0F28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)然,如果我們要在邏輯中獲取到 count 的值時,仍然需要使用 count() 來達(dá)到目的。不過這在語義上是沒有沖突的。B0F28資訊網(wǎng)——每日最新資訊28at.com

let double = move || count() * 2;

與 solid 一樣,這段代碼類似于計算屬性,這個匿名函數(shù)也會被收集成為一個依賴,從而讓 double 也具備響應(yīng)性。B0F28資訊網(wǎng)——每日最新資訊28at.com

當(dāng)我們往組件內(nèi)部傳參數(shù)時,rust 可以通過定義參數(shù)宏來接收和設(shè)置參數(shù)的類型、默認(rèn)值等。B0F28資訊網(wǎng)——每日最新資訊28at.com

#[component]pub fn ProgressBar(  #[prop(default = 100)]  max: u16,  #[prop(into)]  progress: Signal<i32>) -> impl IntoView {  view! {    <progress max=max value=progress />  }}

這個東西類似于面向?qū)ο笾械难b飾器,是給函數(shù)/屬性提供額外能力的一種語法。B0F28資訊網(wǎng)——每日最新資訊28at.com

他有如下幾種用法。B0F28資訊網(wǎng)——每日最新資訊28at.com

#[attribute="value"]#[attribute(key="value")]#[attribute(value)]

例如,我們將一個普通函數(shù)定義為一個組件,則對該函數(shù)使用如下的宏定義。B0F28資訊網(wǎng)——每日最新資訊28at.com

#[component]

接收一個參數(shù) max,默認(rèn)值為 100。B0F28資訊網(wǎng)——每日最新資訊28at.com

#[prop(default = 100)]max: u16,

支持任意類型的值傳入,然后調(diào)用 .into() 去轉(zhuǎn)化。B0F28資訊網(wǎng)——每日最新資訊28at.com

#[prop(into)]progress: Signal<i32>

因此,有了這個宏的幫助,我們的 progress 屬性可以接收一個響應(yīng)式屬性,也可以接收一個普通屬性。通過這種方式解決了 solid 在語法設(shè)計上面臨的困境。B0F28資訊網(wǎng)——每日最新資訊28at.com

<ProgressBar progress=count /><ProgressBar progress=|| 100 />

三、總結(jié)

拋開 rust 的上手難度不談,在語法設(shè)計上,Leptos 的語法設(shè)計我認(rèn)為比 solid 要精妙得多。這是一種更成熟的語法構(gòu)思。B0F28資訊網(wǎng)——每日最新資訊28at.com

但是響應(yīng)式方案本身在語法上確實(shí)存在挑戰(zhàn),例如在 Solid 中還存在更嚴(yán)重的問題就是使用解構(gòu)語法會導(dǎo)致數(shù)據(jù)失去響應(yīng)性,因此最終也只能靠各種編譯手段盡量抹平差異。但黑科技加多了,一不小心就在重新設(shè)計語法了。因此到目前為止,我依然更喜歡 React,他的語法設(shè)計足夠簡潔,編譯手段的侵入性足夠小,更符合 JavaScript 的語法邏輯。B0F28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-90668-0.html來自 Rust 生態(tài)的強(qiáng)烈沖擊?談?wù)?Leptos 在語法設(shè)計上的精妙之處

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: Try-Catch的性能問題及其優(yōu)化策略

下一篇: Vue3 中如何做高性能的拼音搜索,提高用戶體驗(yàn)?

標(biāo)簽:
  • 熱門焦點(diǎn)
  • MIX Fold3包裝盒泄露 新機(jī)本月登場

    小米的全新折疊屏旗艦MIX Fold3將于本月發(fā)布,近日該機(jī)的真機(jī)包裝盒在網(wǎng)上泄露。從圖上來看,新的MIX Fold3包裝盒在外觀設(shè)計方面延續(xù)了之前的方案,變化不大,這也是目前小米旗艦
  • 中興AX5400Pro+上手體驗(yàn):再升級 雙2.5G網(wǎng)口+USB 3.0這次全都有

    2021年11月的時候,中興先后發(fā)布了兩款路由器產(chǎn)品,中興AX5400和中興AX5400 Pro,從產(chǎn)品命名上就不難看出這是隸屬于同一系列的,但在外觀設(shè)計上這兩款產(chǎn)品可以說是完全沒一點(diǎn)關(guān)系
  • Redmi Pad評測:紅米充滿野心的一次嘗試

    從Note系列到K系列,從藍(lán)牙耳機(jī)到筆記本電腦,紅米不知不覺之間也已經(jīng)形成了自己頗有競爭力的產(chǎn)品體系,在中端和次旗艦市場上甚至要比小米新機(jī)的表現(xiàn)來得更好,正所謂“大丈夫生居
  • 一文掌握 Golang 模糊測試(Fuzz Testing)

    模糊測試(Fuzz Testing)模糊測試(Fuzz Testing)是通過向目標(biāo)系統(tǒng)提供非預(yù)期的輸入并監(jiān)視異常結(jié)果來發(fā)現(xiàn)軟件漏洞的方法。可以用來發(fā)現(xiàn)應(yīng)用程序、操作系統(tǒng)和網(wǎng)絡(luò)協(xié)議等中的漏洞或
  • 為什么你不應(yīng)該使用Div作為可點(diǎn)擊元素

    按鈕是為任何網(wǎng)絡(luò)應(yīng)用程序提供交互性的最常見方式。但我們經(jīng)常傾向于使用其他HTML元素,如 div span 等作為 clickable 元素。但通過這樣做,我們錯過了許多內(nèi)置瀏覽器的功能。
  • 小紅書1周漲粉49W+,我總結(jié)了小白可以用的N條漲粉筆記

    作者:黃河懂運(yùn)營一條性教育視頻,被54萬人&ldquo;珍藏&rdquo;是什么體驗(yàn)?最近,情感博主@公主是用鮮花做的,火了!僅僅憑借一條視頻,光小紅書就有超過128萬人,為她瘋狂點(diǎn)贊!更瘋狂的是,這
  • 猿輔導(dǎo)與新東方的兩種“歸途”

    作者|卓心月 出品|零態(tài)LT(ID:LingTai_LT)如何成為一家偉大企業(yè)?答案一定是對&ldquo;勢&rdquo;的把握,這其中最關(guān)鍵的當(dāng)屬對企業(yè)戰(zhàn)略的制定,且能夠站在未來看現(xiàn)在,即使這其中的
  • 2299元起!iQOO Pad明晚首銷:性能最強(qiáng)天璣平板

    5月23日,iQOO如期舉行了新品發(fā)布會,除了首發(fā)安卓最強(qiáng)旗艦處理器的iQOO Neo8系列新機(jī)外,還在發(fā)布會上推出了旗下首款平板電腦——iQOO Pad,其最大的賣點(diǎn)
  • 2299元起!iQOO Pad開啟預(yù)售:性能最強(qiáng)天璣平板

    5月23日,iQOO如期舉行了新品發(fā)布會,除了首發(fā)安卓最強(qiáng)旗艦處理器的iQOO Neo8系列新機(jī)外,還在發(fā)布會上推出了旗下首款平板電腦——iQOO Pad,其搭載了天璣
Top 主站蜘蛛池模板: 闽清县| 微山县| 太和县| 丹巴县| 禄劝| 乌拉特中旗| 定西市| 壶关县| 玉田县| 望谟县| 海阳市| 古交市| 康马县| 当雄县| 吉木乃县| 綦江县| 清远市| 崇义县| 自治县| 偃师市| 青海省| 增城市| 壤塘县| 洛浦县| 余姚市| 准格尔旗| 伊宁县| 清流县| 陇川县| 木里| 汨罗市| 弥勒县| 大丰市| 齐齐哈尔市| 贵南县| 都昌县| 深水埗区| 泰和县| 光泽县| 左云县| 历史|