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

當前位置:首頁 > 科技  > 軟件

來自 Rust 生態的強烈沖擊?談談 Leptos 在語法設計上的精妙之處

來源: 責編: 時間:2024-05-24 17:25:15 269觀看
導讀過去很長一段時間,前端框架們都在往響應式的方向發展。大家都在基于 signal 實現自己的底層。這種趨勢看上去非常火熱,給人一種前端框架不往這個方向發展就落后了一樣。同時又由于 React hooks 的深遠影響,函數式 + 響應

EgV28資訊網——每日最新資訊28at.com

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

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

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

基于響應式能實現細粒度更新,拋去虛擬 DOM 的 diff 成本,性能能夠得到很大的提升。這種設想其實非常美好,但是,在語法設計上會面臨巨大的挑戰。EgV28資訊網——每日最新資訊28at.com

一、Solid.js

我們來觀察并分析一下 solid.js 在語法設計上存在的問題。EgV28資訊網——每日最新資訊28at.com

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

在這個案例中,我們可以使用 createSignal 創建一個響應式數據。這里的問題就在于,返回的響應式數據 count 他不是一個數據,而是一個獲取數據的 getter 方法。EgV28資訊網——每日最新資訊28at.com

因為底層基于 Proxy 來實現,我們需要監聽到數據的變化,那么就需要借助 Proxy 中的 getter 方法來實現,因此反饋到語法上,count 就只能是一個函數。EgV28資訊網——每日最新資訊28at.com

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

當我們在點擊事件中使用該響應式數據時。EgV28資訊網——每日最新資訊28at.com

setCount(count() + 1);

如果你要精準理解 count(),那么理解成本就有點高了,這里的 count() 執行,表達了兩層含義。EgV28資訊網——每日最新資訊28at.com

初始化時,count() 表示會隱式的收集依賴。在跟蹤范圍內,調用 getter 會導致調用 getter 的函數依賴于對應的 signal。當 signal 更新時,這些依賴都會被重新執行。EgV28資訊網——每日最新資訊28at.com

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

例如:EgV28資訊網——每日最新資訊28at.com

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

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

setCount(count() + 1);

這里其實就是語法設計上的沖突問題。同樣的函數執行,由于編譯手段的強勢侵入,在不同的場景里表達了不同的含義。EgV28資訊網——每日最新資訊28at.com

其實 solid.js 的開發團隊也希望 count 就像是直觀表達的那樣,他不是一個 getter,而就是直接是一個值,因此就有類似于如下的語法設計EgV28資訊網——每日最新資訊28at.com

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

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

Solid 的這個語法割裂,在組件傳參的語法設計中,表現得尤為明顯。EgV28資訊網——每日最新資訊28at.com

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

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

這是擁抱響應式的無奈之舉。因為在組件傳參的時候,其實可能存在兩種類型,一種類型是普通數據,例如:EgV28資訊網——每日最新資訊28at.com

<Message msg='hello world' />

而另外一種,就是響應性數據,例如:EgV28資訊網——每日最新資訊28at.com

<Message msg={msg()} />

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

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

<Message msg={msg} />

EgV28資訊網——每日最新資訊28at.com

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

除此之外,正因為有黑科技的強勢侵入,因此 solid 中的 JSX 與 React 中的 JSX 表現并完全不一致,也不能按照常規的表達式去理解。EgV28資訊網——每日最新資訊28at.com

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

二、Leptos

讓我們來看看 rust 生態中,同樣是基于 signal 來實現的響應式框架 Leptos 是如何在語法設計上解決 solid 的割裂問題的。EgV28資訊網——每日最新資訊28at.com

首先,一個非常巧妙的設計就是,在 rsx 中,狀態傳入的括號中,直接接收的就是一個函數EgV28資訊網——每日最新資訊28at.com

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

這里類似于 React 的 render propsEgV28資訊網——每日最新資訊28at.com

這樣看著就非常的舒服。因為聲明的 count 是一個函數,模板渲染中需要的也是一個函數,語法表現就很一致,按照這個設計,我們就可以不用寫 count() 了。EgV28資訊網——每日最新資訊28at.com

這個小的語法設計細節的調整,讓整個語法都變得更加一致。EgV28資訊網——每日最新資訊28at.com

當我們更新時EgV28資訊網——每日最新資訊28at.com

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

當我們要往子組件中傳遞參數時EgV28資訊網——每日最新資訊28at.com

<ProgressBar progress=count />

當語法規則發生一些簡單的調整,我們會發現,在大多數情況下,count 的使用都保持了一致性,而不是像 solid 那樣在不同的場景之下有不同的行為。EgV28資訊網——每日最新資訊28at.com

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

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

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

當我們往組件內部傳參數時,rust 可以通過定義參數宏來接收和設置參數的類型、默認值等。EgV28資訊網——每日最新資訊28at.com

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

這個東西類似于面向對象中的裝飾器,是給函數/屬性提供額外能力的一種語法。EgV28資訊網——每日最新資訊28at.com

他有如下幾種用法。EgV28資訊網——每日最新資訊28at.com

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

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

#[component]

接收一個參數 max,默認值為 100。EgV28資訊網——每日最新資訊28at.com

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

支持任意類型的值傳入,然后調用 .into() 去轉化。EgV28資訊網——每日最新資訊28at.com

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

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

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

三、總結

拋開 rust 的上手難度不談,在語法設計上,Leptos 的語法設計我認為比 solid 要精妙得多。這是一種更成熟的語法構思。EgV28資訊網——每日最新資訊28at.com

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

本文鏈接:http://m.www897cc.com/showinfo-26-90668-0.html來自 Rust 生態的強烈沖擊?談談 Leptos 在語法設計上的精妙之處

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

上一篇: Try-Catch的性能問題及其優化策略

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

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
亚洲片在线观看| 欧美日本高清视频| 欧美影院在线播放| 久久精品国产免费看久久精品| 久久久久久九九九九| 欧美成人午夜影院| 欧美日韩亚洲系列| 国产色视频一区| 亚洲国产成人久久综合| 99re66热这里只有精品4| 午夜精品久久久久久久99樱桃 | 国产亚洲日本欧美韩国| 在线观看欧美| 一区二区日本视频| 久久久999精品| 欧美日韩亚洲高清一区二区| 国产日韩精品一区二区三区| 亚洲精品男同| 欧美伊人久久大香线蕉综合69| 欧美高清在线视频观看不卡| 国产精品久久久久永久免费观看 | 性欧美video另类hd性玩具| 免费亚洲婷婷| 国产毛片精品视频| 亚洲精品偷拍| 久久久精品999| 欧美视频在线观看 亚洲欧| 国内精品久久久久影院薰衣草| 一本色道综合亚洲| 久久亚洲图片| 国产精品免费小视频| 亚洲国产综合91精品麻豆| 小嫩嫩精品导航| 欧美日韩国产成人在线观看| 激情久久影院| 午夜精品www| 欧美日韩国语| 亚洲国产精选| 久久久精品午夜少妇| 国产精品久久77777| 亚洲精品人人| 久久久人成影片一区二区三区观看 | 欧美日韩精品在线播放| 1000部国产精品成人观看| 亚洲免费视频中文字幕| 欧美久久电影| 亚洲高清视频在线| 欧美在线视频观看免费网站| 欧美视频在线看| 亚洲三级视频在线观看| 久久久久久久波多野高潮日日| 国产精品日韩二区| 一区二区欧美在线| 欧美日韩国产成人高清视频| 亚洲成色777777在线观看影院| 欧美在线视频导航| 国产日韩欧美黄色| 午夜精品久久久久久久蜜桃app| 欧美午夜电影一区| 日韩亚洲精品在线| 欧美顶级大胆免费视频| 一区二区三区在线高清| 久久精品国产精品亚洲综合| 国产伦精品一区二区三区视频黑人| 欧美激情在线免费观看| 国产主播一区| 欧美一区午夜精品| 国产欧美日韩在线播放| 亚洲曰本av电影| 国产精品盗摄久久久| 一区二区三区鲁丝不卡| 欧美巨乳在线| 日韩午夜精品| 欧美视频一区二区三区在线观看 | 国内欧美视频一区二区| 欧美中文字幕| 国产在线欧美日韩| 久久精品一区二区国产| 国产视频一区在线| 欧美专区18| 激情六月婷婷久久| 久久亚洲一区二区| 91久久精品日日躁夜夜躁欧美| 欧美成人午夜激情在线| 亚洲精品一区在线观看香蕉| 欧美韩日一区二区三区| 99国内精品| 国产精品久久久久久久久久三级| 亚洲一区二区三区免费观看| 国产精品一区二区你懂的| 午夜精品久久一牛影视| 国产日韩欧美一区二区三区在线观看 | 欧美日韩在线播放三区四区| 日韩一区二区精品葵司在线| 欧美精品色网| 国产精品99久久久久久宅男| 国产精品综合不卡av| 欧美中文字幕久久| 尤物九九久久国产精品的特点| 免费亚洲电影在线观看| 亚洲精品国产精品国自产观看| 久久精品水蜜桃av综合天堂| 一级成人国产| 国产亚洲激情在线| 国产欧美日韩综合一区在线播放| 蜜桃精品久久久久久久免费影院| 久久精品一区四区| 久久福利一区| 国产精品一区视频网站| 国产综合亚洲精品一区二| 在线精品观看| 亚洲一区二区影院| 久久激情视频久久| 欧美久久视频| 欧美视频在线观看一区| 影音国产精品| 久久国产高清| 欧美成人激情在线| 久久一区二区三区超碰国产精品| 欧美精品激情| 欧美激情一区二区三区高清视频| 欧美日韩性视频在线| 欧美性生交xxxxx久久久| 在线观看国产成人av片| 亚洲欧美激情精品一区二区| 午夜在线电影亚洲一区| 激情91久久| 欧美日本国产视频| 香蕉久久国产| 亚洲国产日韩欧美综合久久| 国产精品国内视频| 久久综合久久综合九色| 夜夜嗨av色一区二区不卡| 国产区欧美区日韩区| 免费一级欧美片在线播放| 午夜精品国产更新| 欧美日韩高清一区| 亚洲第一黄色| 久久久最新网址| 欧美精品手机在线| 狠狠色综合网| 午夜欧美大片免费观看| 欧美在线在线| 国产乱码精品一区二区三区不卡| 久久狠狠婷婷| 亚洲国产高清自拍| 国产精品老牛| 欧美激情综合网| 欧美一区日本一区韩国一区| 伊人久久大香线蕉综合热线| 欧美激情第五页| 午夜精品久久久久久99热软件| 国产日韩一区| 亚洲欧美在线视频观看| 久久久久久亚洲综合影院红桃| 99pao成人国产永久免费视频| 国产一区二区在线观看免费| 欧美日韩亚洲视频一区| 久久精品视频在线看| 亚洲天堂激情| 亚洲日本免费电影| 黄色亚洲大片免费在线观看| 国产精品视频内| 欧美日韩美女| 欧美mv日韩mv国产网站| 久久久精品欧美丰满| 亚洲欧美日本精品| 亚洲视频999| 亚洲六月丁香色婷婷综合久久| 黄色欧美成人| 国产亚洲精品福利| 国产精品热久久久久夜色精品三区 | 久久久久久久久蜜桃| 亚洲欧美清纯在线制服| 夜夜嗨av一区二区三区网站四季av| 在线欧美亚洲| 国内精品视频在线观看| 国产欧美亚洲一区| 国产精品久久久久久久久果冻传媒| 欧美日本一区二区三区| 欧美成人伊人久久综合网| 老司机成人网| 久久综合五月天婷婷伊人| 久久精品国产一区二区三| 午夜精品剧场| 亚洲综合999| 亚洲免费在线观看| 亚洲网站视频福利| 中日韩男男gay无套| 艳女tv在线观看国产一区| 亚洲精品综合在线| 亚洲精品黄色| 欧美金8天国| 男男成人高潮片免费网站| 久久亚洲不卡| 老巨人导航500精品| 久久嫩草精品久久久精品一| 久久成人资源| 欧美日韩免费一区二区三区| 久久久精品国产一区二区三区| 欧美在线啊v| 欧美专区第一页| 久久成人资源| 久久色中文字幕|