【SolidJs】仅次于原生JS的超级性能!SolidJs框架教程【上】(1)

简介: 背景今天被战友种草了一款前端框架,打开链接看文章,在各个指标的比较下,SolidJs脱颖而出,下面简单介绍一下这个框架,然后开始记录一下学习笔记。(Golang的事情暂时放一放,毕竟咱是专业前端「手动狗头」)。

背景

今天被战友种草了一款前端框架,打开链接看文章,在各个指标的比较下,SolidJs脱颖而出,下面简单介绍一下这个框架,然后开始记录一下学习笔记。(Golang的事情暂时放一放,毕竟咱是专业前端「手动狗头」)。

SolidJs简介

SolidJs作为一个新星)可谓是各个厂牌的集大成者,它支持JSXFragmentsContextPortalsLazy等等,而且是继HyperApp和Svelte后,第三个比纯JS实现更小的库。

JSX + template

SolidJs在保持JSX语法的同时,做了一些template的规范,比如它的ForIndexSwitchMatch.....既保留了JSX语法的灵活性,又再某些程度提高了编译速度,perfect!

NO DOM DIFF

SolidJs并不像Vue&React采用了虚拟dom,解决了内存占用过多的问题

SolidJs教程

Hello World

import { render } from 'solid-js/web'
function HelloWorld() {
    return <p>Hello World</p>
}
render(() => <HelloWorld />, document.getElementById("app"))
复制代码

组件的使用

SolidJs中,组件的含义与React基本一致,即组件即函数,举个🌰

nested.tsx

export default () => <p>from nested.tsx</p>
复制代码

main.tsx

import {render} from 'solid-js/web'
import Nested from './nested'
function App() {
 return (
     <Nested />
 )
}
render(() => <App />, document.getElementById("app"))
复制代码

Fragment

如果返回了2个元素,可以用Fragement包装起来,举个🌰

import {render} from 'solid-js/web'
import Nested from './nested'
function App() {
    return (
        <>
            <h1>组件:Nested</h1>
            <Nested />
        </>
    )
}
render(() => <App/>, document.getElementById('app'))
复制代码

Signal

Signal是最核心的响应式基本要素,创建一个Signal的语法为:

const [count, setCount] = createSignal(0)
复制代码

当然,createSignal需要从solid-js中导出:

import { createSignal } from 'solid-js'
复制代码

传递给createSignal的值就是count的初始值,返回一个带有2个函数的数组,一个是getter,一个是setter,可以使用解构随意命名这些参数,例如上面那个🌰,count就是getter,setCount就是setter。

注意:第一个返回值是一个getter,而不是0值本身。

举一个计数器的🌰:

import { render } from 'solid-js/web'
import { createSignal } from 'solid-js'
function App() {
    const [count, setCount] = createSignal(0)
    setInterval(() => {
        setCount(count() + 1)
    }, 1000)
    return (
        <div>count的值为:{count()}</div>
    )
}
render(() => <App/>, document.getElementById('app'))
复制代码

setCount也可以接受一个函数,举个🌰

setInterval(() => {
    setCount(c => c +1 )
}, 1000)
复制代码

派生Signal

类似于Vue中的computed,举个🌰

import { render } from 'solid-js/web'
import { createSignal } from 'solid-js'
function App() {
    const [count, setCount] = createSignal(0)
    const doubleCount = () => count() * 2
    return (
        <>
            <div>doubleCount: {doubleCount()}</div>
            <button onClick={() => setCount(c => c+1)}>点击</button>
        </>
    )
}
render(() => <App/>, docu3ment.getElementById('app'))
复制代码

Effect

通过从sloid-js导入createEffect来创建Effect,接受一个函数,并监视其执行情况。createEffec 会自动订阅在执行期间读取的所有Signal,并在这些Signal值其中一个发生变化时,重新运行该函数,举个🌰

import { render } from 'solid-js/web'
import { createSignal, createEffect } from 'solid-js'
function App() {
    const [count, setCount] = createSignal(0)
    createEffect(() => {
        console.log("当前 count:", count())
    })
    return (
        <button onClick={() => setCount(c => c + 1)}>点击</button>
    )
}
render(() => <App/>, document.getElementById('app'))
复制代码

Show

Show组件用来控制DOM是否显示,举个🌰

import { render } from 'solid-js/web';
import { createSignal, Show } from 'solid-js';
function App() {
    const [loggedIn, setLoggedIn] = createSignal(false);
    const toggle = () => setLoggedIn(!loggedIn())
    return (
        <Show when={loggedIn()} fallback={() => <button onClick={toggle}>Log in</button>}>
            <button onClick={toggle}>Log out</button>
        </Show>
    )
}
render(() => <App />, document.getElementById('app'))
复制代码

Vue不同的是,solidJs是在Show组件中通过when关键字后加条件来判断是否显示,通过fallback关键字来显示上一个条件为false时的组件。

For

For是SolidJs遍历的列表组件,举个🌰

import { render } from 'solid-js/web';
import { createSignal, For } from 'solid-js';
function App() {
  const [dogs, setDogs] = createSignal([
    { id: 0, name: "dog1" },
    { id: 1, name: "dog2" },
    { id: 2, name: "dog3" },
  ]);
  return (
    <For each={dogs()}>
      {(dog, i) => (
        <div>
          id:{i()}; name:{dog.name}
        </div>
      )}
    </For>
  );
}
render(() => <App />, document.getElementById('app'))
复制代码

Index

Index组件也是用来遍历的,上面的🌰,用Index组件进行遍历:

<Index each={dogs()}>
    {(dog, i) => (
        {i}, {dog().name}
    )}
</Index>
复制代码

可以发现,IndexFor具有相似的功能,不同点是,For中索引是SignalIndex中数据项是Signal

Switch

Switch组件是Show组件的扩展,如果在一个多层条件判断的情况下,使用Show组件会发生多级嵌套,代码臃肿,使用Switch/Match可以很好的解决这种情况,举个🌰

import { render } from 'solid-js/web';
import { createSignal, Switch, Match } from 'solid-js'
function App() {
    const [age, setAge] = createSignal(12);
      return (
        <Switch fallback={<div>未知</div>}>
          <Match when={age() < 18}>
            <div>未成年</div>
          </Match>
          <Match when={age() >= 18 && age() < 60}>
            <div>成年人</div>
          </Match>
          <Match when={age() >= 60}>
            <div>老年人</div>
          </Match>
        </Switch>
      );
}
render(() => <App />, document.getElementById('app'))
复制代码

Dynamic

Dynamic组件处可以让开发者编写<Switch>/<Match>组件变得更简练,举个栗子:

import { render, Dynamic } from "solid-js/web";
import { createSignal, Switch, Match, For } from "solid-js";
const RedThing = () => <strong style="color: red">Red Thing</strong>;
const GreenThing = () => <strong style="color: green">Green Thing</strong>;
const BlueThing = () => <strong style="color: blue">Blue Thing</strong>;
const options = {
  red: RedThing,
  green: GreenThing,
  blue: BlueThing,
};
function App() {
  const [selected, setSelected] = createSignal("red");
  return (
    <>
      <select
        value={selected()}
        onInput={(e) => setSelected(e.currentTarget.value)}
      >
        <For each={Object.keys(options)}>
          {(color) => <option value={color}>{color}</option>}
        </For>
      </select>
      <Dynamic component={options[selected()]} />
    </>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

Portal

Portal组件可以在正常顺序之外插入元素,默认情况下,Portal的子内容将从正常的DOM顺序中拿出来,插入到document.body下的

中,举个🌰

main.tsx

import { render, Portal } from "solid-js/web";
import "./styles.css";
function App() {
  return (
    <div class="app-container">
      <p>Just some text inside a div that has a restricted size.</p>
      <Portal>
        <div class="popup">
          <h1>Popup</h1>
          <p>Some text you might need for something or other.</p>
        </div>
      </Portal>
    </div>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

styles.css

.app-container {
  width: 200px;
  height: 100px;
  overflow: hidden;
}
.popup {
  position: relative;
  z-index: 2;
  background: #ddd;
  padding: 1rem;
  min-height: 200px;
  width: 200px;
}
.popup::after {
  content: " ";
  position: absolute;
  bottom: 100%;
  left: 50%;
  margin-left: -5px;
  border-width: 5px;
  border-style: solid;
  border-color: transparent transparent #ddd transparent;
}
复制代码

效果是这样的:

网络异常,图片无法展示
|

ErrorBoundary

ErrorBoundary是一个可以捕获子组件任何未知产生的JavaScript错误,并显示发生错误的报错信息,举个🌰

import { render } from "solid-js/web";
import { ErrorBoundary } from "solid-js";
const Broken = (props) => {
  throw new Error("Oh No");
  return <>Never Getting Here</>
}
function App() {
  return (
    <>
      <div>Before</div>
      <ErrorBoundary fallback={(err) => err}>
        <Broken />
      </ErrorBoundary>
      <div>After</div>
    </>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

效果如下:

网络异常,图片无法展示
|

目录
相关文章
|
12天前
|
前端开发 JavaScript 大数据
关于JavaScript性能问题的误解
JavaScript 是单线程语言,代码逐行执行,遇到大数据量计算可能影响性能。前端同事担心遍历大量数据会导致性能问题,但实际上,即使遍历1000、10000条数据,耗时也较少。测试代码执行时间有三种方法:Date.now、console.time 和 performance.now,其中 performance.now 精度最高。开发中不必过度担忧遍历带来的性能损耗,保持代码清晰更重要。
22 5
|
1月前
|
前端开发 JavaScript Java
JavaScript闭包深入剖析:性能剖析与优化技巧
JavaScript 闭包是强大而灵活的特性,广泛应用于数据封装、函数柯里化和事件处理等场景。闭包通过保存外部作用域的变量,实现了私有变量和方法的创建,提升了代码的安全性和可维护性。然而,闭包也可能带来性能问题,如内存泄漏和执行效率下降。为优化闭包性能,建议采取以下策略:及时解除对不再使用的闭包变量的引用,减少闭包的创建次数,使用 WeakMap 管理弱引用,以及优化闭包结构以减少作用域链查找的开销。在实际开发中,无论是 Web 前端还是 Node.js 后端,这些优化措施都能显著提升程序的性能和稳定性。
131 70
|
2月前
|
JavaScript 前端开发 测试技术
盘点原生JavaScript中直接触发事件的方式
本文全面探讨了原生JavaScript中触发事件的多种方式,包括`dispatchEvent`、`Event`构造函数、`CustomEvent`构造器、直接调用事件处理器以及过时的`createEvent`和`initEvent`方法。通过技术案例分析,如模拟点击事件、派发自定义数据加载事件和实现提示框系统,帮助开发者掌握这些方法在实际开发中的应用,提升灵活性与兼容性。
51 3
|
3月前
|
数据采集 人工智能 自然语言处理
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
Midscene.js 是一款基于 AI 技术的 UI 自动化测试框架,通过自然语言交互简化测试流程,支持动作执行、数据查询和页面断言,提供可视化报告,适用于多种应用场景。
841 1
Midscene.js:AI 驱动的 UI 自动化测试框架,支持自然语言交互,生成可视化报告
|
3月前
|
JSON 缓存 负载均衡
Node.js 的性能
Node.js 的性能
119 12
|
4月前
|
存储 缓存 监控
如何使用内存监控工具来优化 Node.js 应用的性能
需要注意的是,不同的内存监控工具可能具有不同的功能和特点,在使用时需要根据具体工具的要求和操作指南进行正确使用和分析。
103 31
|
4月前
|
监控 JavaScript 算法
如何使用内存监控工具来定位和解决Node.js应用中的性能问题?
总之,利用内存监控工具结合代码分析和业务理解,能够逐步定位和解决 Node.js 应用中的性能问题,提高应用的运行效率和稳定性。需要耐心和细致地进行排查和优化,不断提升应用的性能表现。
233 77
|
4月前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
4月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
82 2
|
4月前
|
存储 缓存 JavaScript
如何优化Node.js应用的内存使用以提高性能?
通过以上多种方法的综合运用,可以有效地优化 Node.js 应用的内存使用,提高性能,提升用户体验。同时,不断关注内存管理的最新技术和最佳实践,持续改进应用的性能表现。
192 62

热门文章

最新文章