首頁 > web前端 > css教學 > 固體JavaScript庫簡介

固體JavaScript庫簡介

尊渡假赌尊渡假赌尊渡假赌
發布: 2025-03-20 09:42:17
原創
830 人瀏覽過

SolidJS:一款高性能的響應式JavaScript UI庫

Introduction to the Solid JavaScript Library

Solid是一個用於創建用戶界面的響應式JavaScript庫,它無需虛擬DOM。它將模板編譯成真正的DOM節點,並將更新包裝在細粒度的反應中,因此當狀態更新時,只有相關的代碼才會運行。

這種方式使得編譯器可以優化初始渲染,運行時可以優化更新。這種對性能的關注使其成為最受好評的JavaScript框架之一。

我對此很好奇,想嘗試一下,所以我花了一些時間創建了一個小型待辦事項應用程序,來探索這個框架如何處理渲染組件、更新狀態、設置存儲等等。

如果您迫不及待地想查看最終代碼和結果,請查看最終演示: [此處應插入最終演示鏈接,原文未提供]

快速入門

與大多數框架一樣,我們可以從安裝npm包開始。要將該框架與JSX一起使用,請運行:

 npm install solid-js babel-preset-solid
登入後複製

然後,我們需要將babel-preset-solid添加到我們的Babel、webpack或Rollup配置文件中:

 "presets": ["solid"]
登入後複製

或者,如果您想搭建一個小型應用程序,您也可以使用他們的模板之一:

 # 從Solid模板創建一個小型應用程序npx degit solidjs/templates/js my-app

# 更改到創建的項目目錄cd my-app

# 安裝依賴項npm i # 或yarn 或pnpm

# 啟動開發服務器npm run dev
登入後複製

支持TypeScript,如果您想啟動一個TypeScript項目,請將第一個命令更改為npx degit solidjs/templates/ts my-app

創建和渲染組件

渲染組件的語法類似於React.js,因此可能看起來很熟悉:

 import { render } from "solid-js/web";

const HelloMessage = props =><div> Hello {props.name}</div> ;

render(
  () =><hellomessage name="Taylor"></hellomessage> ,
  document.getElementById("hello-example")
);
登入後複製

我們需要先導入render函數,然後創建一個帶有文本和prop的div,並調用render,傳入組件和容器元素。

這段代碼隨後被編譯成真正的DOM表達式。例如,上面的代碼示例,一旦被Solid編譯,看起來像這樣:

 import { render, template, insert, createComponent } from "solid-js/web";

const _tmpl$ = template(`<div> Hello</div> `);

const HelloMessage = props => {
  const _el$ = _tmpl$.cloneNode(true);
  insert(_el$, () => props.name);
  return _el$;
};

render(
  () => createComponent(HelloMessage, { name: "Taylor" }),
  document.getElementById("hello-example")
);
登入後複製

Solid Playground非常酷,它顯示Solid有不同的渲染方式,包括客戶端、服務器端和帶有水合的客戶端。

使用Signals跟踪變化的值

Solid使用一個名為createSignal的hook,它返回兩個函數:一個getter和一個setter。如果您習慣使用像React.js這樣的框架,這可能看起來有點奇怪。您通常期望第一個元素是值本身;但是,在Solid中,我們需要顯式調用getter來攔截讀取值的位置,以便跟踪其更改。

例如,如果我們正在編寫以下代碼:

 const [todos, addTodos] = createSignal([]);
登入後複製

記錄todos不會返回值,而是一個函數。如果我們想使用該值,我們需要調用該函數,例如todos()

對於一個小的待辦事項列表,這將是:

 import { createSignal } from "solid-js";

const TodoList = () => {
  let input;
  const [todos, addTodos] = createSignal([]);

  const addTodo = value => {
    return addTodos([...todos(), value]);
  };

  return (
    <h1>To do list:</h1>
    <input type="text" ref="{el"> input = el} />
    <button onclick="{()"> addTodo(input.value)}>Add item</button>
    
登入後複製
    {todos().map(item => (
  • {item}
  • ))}
); };

上面的代碼示例將顯示一個文本字段,單擊“添加項目”按鈕後,將使用新項目更新todos並在列表中顯示它。

這看起來可能與使用useState非常相似,那麼使用getter有什麼不同呢?考慮以下代碼示例:

 console.log("Create Signals");
const [firstName, setFirstName] = createSignal("Whitney");
const [lastName, setLastName] = createSignal("Houston");
const [displayFullName, setDisplayFullName] = createSignal(true);

const displayName = createMemo(() => {
  if (!displayFullName()) return firstName();
  return `${firstName()} ${lastName()}`;
});

createEffect(() => console.log("My name is", displayName()));

console.log("Set showFullName: false ");
setDisplayFullName(false);

console.log("Change lastName ");
setLastName("Boop");

console.log("Set showFullName: true ");
setDisplayFullName(true);
登入後複製

運行上面的代碼將得到:

 <code>Create Signals My name is Whitney Houston Set showFullName: false My name is Whitney Change lastName Set showFullName: true My name is Whitney Boop</code>
登入後複製

需要注意的主要一點是,在設置新的lastName後,“My name is...”沒有被記錄。這是因為此時沒有任何內容正在監聽lastName()的更改。只有當displayFullName()的值更改時, displayName()的新值才會被設置,這就是為什麼當setShowFullName被設置為true時,我們可以看到新的lastName被顯示。

這為我們提供了一種更安全的方式來跟踪值的更新。

響應式原語

在最後一個代碼示例中,我介紹了createSignal ,還有一些其他的原語: createEffectcreateMemo

createEffect

createEffect跟踪依賴項,並在每次依賴項發生更改的渲染後運行。

 // 不要忘記首先使用'import { createEffect } from "solid-js";' 導入它const [count, setCount] = createSignal(0);

createEffect(() => {
  console.log("Count is at", count());
});
登入後複製

每次count()的值發生更改時,都會記錄“Count is at...”

createMemo

createMemo創建一個只讀信號,每當執行的代碼的依賴項更新時,它都會重新計算其值。當您想要緩存一些值並訪問它們而無需重新評估它們(直到依賴項更改)時,可以使用它。

例如,如果我們想顯示一個計數器100次並在單擊按鈕時更新值,使用createMemo將允許重新計算僅在每次點擊時發生一次:

 function Counter() {
  const [count, setCount] = createSignal(0);
  // 不用createMemo包裝counter會調用100次// const counter = () => {
  // return count();
  // }

  // 用createMemo包裝counter,每次更新只調用一次// 不要忘記首先使用'import { createMemo } from "solid-js";' 導入它const counter = createMemo(() => count());

  return (
    <div>
      <button onclick="{()"> setCount(count() 1)}>Count: {count()}</button>
      <div>1. {counter()}</div>
      <div>2. {counter()}</div>
      <div>3. {counter()}</div>
      <div>4. {counter()}</div>
    </div>
  );
}
登入後複製

生命週期方法

Solid公開了幾個生命週期方法,例如onMountonCleanuponError 。如果我們希望某些代碼在初始渲染後運行,我們需要使用onMount

 // 不要忘記首先使用'import { onMount } from "solid-js";' 導入它onMount(() => {
  console.log("I mounted!");
});
登入後複製

onCleanup類似於React中的componentDidUnmount ——它在響應式作用域重新計算時運行。

onError在最近的子作用域中發生錯誤時執行。例如,當數據獲取失敗時,我們可以使用它。

存儲

要為數據創建存儲,Solid公開了createStore ,其返回值是一個只讀代理對象和一個setter函數。

例如,如果我們將我們的待辦事項示例更改為使用存儲而不是狀態,它將如下所示:

 const [todos, addTodos] = createStore({ list: [] });

createEffect(() => {
  console.log(todos.list);
});

onMount(() => {
  addTodos('list', (list) => [...list, { item: "a new todo item", completed: false }]);
});
登入後複製

上面的代碼示例將首先記錄一個帶有空數組的代理對象,然後記錄一個帶有數組的代理對象,該數組包含對象{item: "a new todo item", completed: false}

需要注意的是,如果不訪問其屬性,則無法跟踪頂級狀態對象——這就是為什麼我們記錄todos.list而不是todos的原因。

如果我們只在createEffect中記錄todos ,我們將看到列表的初始值,但不會看到在onMount中進行更新後的值。

要更改存儲中的值,我們可以使用在使用createStore時定義的設置函數來更新它們。例如,如果我們想將待辦事項列表項更新為“已完成”,我們可以通過這種方式更新存儲:

 const [todos, setTodos] = createStore({
  list: [{ item: "new item", completed: false }]
});

const markAsComplete = text => {
  setTodos(
    "list",
    (i) => i.item === text,
    "completed",
    (c) => !c
  );
};

return (
  <button onclick="{()"> markAsComplete("new item")}>Mark as complete</button>
);
登入後複製

控制流

為了避免在使用.map()等方法時在每次更新時浪費性地重新創建所有DOM節點,Solid允許我們使用模板助手。

其中一些可用,例如For用於循環遍歷項目, Show用於有條件地顯示和隱藏元素, SwitchMatch用於顯示與特定條件匹配的元素,等等!

以下是一些顯示如何使用它們的示例:

<for each="{todos.list}" fallback="{<div"> Loading... }>
  {(item) =><div> {item}</div> }
</for>
<show when="{todos.list[0]?.completed}" fallback="{<div"> Loading... }>
  <div>1st item completed</div>
</show>
<switch fallback="{<div"> No items }>
  <match when="{todos.list[0]?.completed}"><completedlist></completedlist></match>
  <match when="{!todos.list[0]?.completed}"><todolist></todolist></match>
</switch>
登入後複製

演示項目

這是對Solid基礎知識的快速介紹。如果您想試用它,我創建了一個入門項目,您可以通過單擊下面的按鈕將其自動部署到Netlify並克隆到您的GitHub!

[此處應插入部署到Netlify的按鈕,原文未提供] 該項目包括Solid項目的默認設置,以及我在這篇文章中提到的基本概念的示例待辦事項應用程序,以幫助您入門!

這個框架比我在這裡介紹的要多得多,所以請隨意查看文檔以了解更多信息!

以上是固體JavaScript庫簡介的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板