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

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

onMount 生命周期

引用一段官方的话:

Solid 中只有少量的生命周期,因为一切的存活销毁都由响应系统控制。响应系统是同步创建和更新的,因此唯一的调度就是将逻辑写到更新结束的 Effect 中。

举个🌰

import { render } from "solid-js/web";
import { createSignal, onMount, For } from "solid-js";
function App() {
  const [photos, setPhotos] = createSignal([]);
  onMount(async () => {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/photos?_limit=20`
    );
    setPhotos(await res.json());
  });
  return (
    <>
      <h1>photos</h1>
      <div class="photos">
        <For each={photos()} fallback={<p>Loading</p>}>
          {(photo, i) => (
            <figure>
              <img src={photo.thumbnailUrl} alt={photo.title} />
              <figcaption>{photo.title}</figcaption>
            </figure>
          )}
        </For>
      </div>
    </>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

onCleanup

onCleanup函数可以执行一些销毁操作,举个栗子

import { render } from "solid-js/web";
import { createSignal, onCleanup } from "solid-js";
function Counter() {
  const [count, setCount] = createSignal(0);
  const timer = setInterval(() => setCount(count() + 1), 1000);
  onCleanup(() => clearInterval(timer));
  return <div>Count: {count()}</div>;
}
render(() => <Counter />, document.getElementById("app"));
复制代码

事件

在SolidJs中,事件均以on为前缀,举个🌰

import { render } from "solid-js/web";
import { createSignal } from "solid-js";
import "./style.css";
function App() {
  const [pos, setPos] = createSignal({ x: 0, y: 0 });
  function handleMouseMove(event) {
    setPos({
      x: event.clientX,
      y: event.clientY,
    });
  }
  return (
    <div onmousemove={handleMouseMove}>
      The mouse position is {pos().x} x {pos().y}
    </div>
  );
}
render(() => <App />, document.getElementById("app"));
复制代码

动态样式 Style

SolidJs中的style属性接受样式字符串和对象,但需要注意一点,官话:

对象形式不同于 Element.prototype.style,Solid 通过调用 style.setProperty 的封装来进行样式设置。

意味着样式的键需要采用中划线的方式,例如background-color而不是backgroundColor,但是这意味着可以设置CSS变量:

<div style={{'--my-custom-color': themeColor()}}></div>
复制代码

举个🌰

import { render } from "solid-js/web";
import { createSignal } from "solid-js";
function App() {
  const [num, setNum] = createSignal(0);
  setInterval(() => setNum((num() + 1) % 255), 30)
  return <div style={{
      color: `rgb(${num()}, 180, ${num()})`,
      'font-size': `${num()}px`
  }}>Some Text</div>;
}
render(() => <App />, document.getElementById('app'));
复制代码

动态类名 ClassList

SolidJs支持使用 classclassName设置元素的classname属性,classList用来设置多个class名,key是类名,value是一个boolean,举个🌰

function App() {
    const [current, setCurrent] = createSignal('foo')
    return <>
        <button class={current() === 'foo' ? 'selected' : ''} onClick={setCurrent('foo')}>foo</button>
        <button class={current() === 'bar' ? 'selected' : ''} onClick={setCurrent('bar')}>bar</button>
        <button class={current() === 'baz' ? 'selected' : ''} onClick={setCurrent('bar')}>baz</button>
    </>
}
复制代码

当然上面的代码也可以用classList,🌰:

<button classList={{'selected': current() === 'foo'}} onClick={setCurrent('foo')}>foo</button>
复制代码

Ref

SolidJs中,可以通过ref属性获取元素的引用,官话:

赋值行为是在元素创建时,在 DOM 被追加前发生的。 只需声明一个变量,元素引用就会赋值给该变量。

举个🌰

let myDiv;
<div ref={myDiv}>my Div</div>
复制代码

就可以了...

属性绑定/扩展

利用...扩展运算符,可以直接把属性传进子组件,举个🌰

main.tsx

import { render } from "solid-js/web";
import Info from "./info";
const pkg = {
  name: "dog",
  age: 3,
  gender: 0,
};
function App() {
  return <Info name={pkg.name} age={pkg.age} gender={pkg.gender}></Info>;
}
render(() => <App />, document.getElementById("app"));
复制代码

info.tsx

export default function Info(props) {
  console.log(props)
  return (
    <div>
      <p>name: {props.name}</p>
      <p>age: {props.age}</p>
      <p>gender: {props.gender === 0 ? "girl" : "boy"}</p>
    </div>
  );
}
复制代码

上面的main.tsx可以这样改造一下:

function App() {
  return <Info {...pkg}></Info>;
}
复制代码

是不是省了很多事儿!

指令

SolidJs可以通过use自定义指令,自定义指令仅仅只是一个形式为(element, valueAccesor)的函数,其中valueAccesor是一个获取绑定值的函数,只要函数是在作用域中导入的,就可以通过use:使用。

重要提示:use: 需要被编译器检测并进行转换,并且函数需要在作用域内,因此不能作为传值的一部分或在组件上使用。

举一个modal的🌰:

main.tsx

import { render } from "solid-js/web";
import { createSignal, Show } from "solid-js";
import clickOutside from './click-outside'
function App() {
    const [show, setShow] = createSignal(false)
    return (
        <Show when={show()} fallback={<button onClick={setShow(true)}>show Modal</button>}>
            <div class="modal" use:clickOutside={show(false)}>modal box</modal>
        </Show>
    )
}
render(() => <App />, document.getElementById("app"));
复制代码

click-outside.tsx

import { onCleanup } from 'solid-js';
export default function clickOutside(el, accessor) {
    const onClick = (e) => !el.contains(e.target) && accessor()?.();
    document.body.addEventListener('click', onClick)
    onCleanup(() => document.removeEventListener('click', onClick))
}
复制代码

props

SolidJs中的props传值上面已经有🌰了,很简单,再举个🌰

main.tsx

import WelcomeWord from './welcomeWord'
function App() {
    reutrn (
        <>
            <WelcomeWord gretting="Hi" name="Bob"></WelcomeWord>
        </>
    )
}
复制代码

welcomeWord.tsx

export default function welcomeWord(props) {
    return <h1>{props.gretting || 'hello'} {props.name || 'Alice'}</h1>
}
复制代码

props赋值默认值通过mergeProps操作,上面的🌰就可以改成这样

welcomeWord.tsx

import { mergeProps } from 'solid-js'
export default function welcomeWord(props) {
    const merged = mergeProps({ greeting: 'hello', name: 'Alice' }, props)
    return <h1>{merged.greeting} {merged.name} </h1>
}
复制代码

就很完美,官话:

Solid 有一些工具函数可以帮助我们处理 props。 第一个 mergeProps 函数听起来很像它名字描述得那样合并 props。mergeProps 将潜在的响应式对象合并而不会失去响应式性。最常见的情况就是是为组件设置默认 props。

props分离

在SolidJs中解构一个props会失去数据的响应性,可以通过splitProps来分离一个props,举个🌰

main.tsx

import { render } from "solid-js/web";
import { createSignal } from "solid-js";
import Greeting from "./greeting";
function app() {
    const [name, setName] = createSignal("Jack")
    return <>
        <Greeting greeting="Yo" name={name()} style="color: teal;" />
        <button onClick={setName("Alice")}>set name</button>
    </>
}
render(() => <App />, document.getElementById('app'));
复制代码

greeting.tsx

export default function Greeting(props) {
    let { greeting, name, ...others } = props
    return <h3 {...others}>{greeting} {name}</h3>
}
复制代码

这种方式修改name的时候,发现子组件并没有修改,所以需要使用splitProps

import { splitProps } from "solid-js";
export default function Greeting(props) {
  const [local, others] = splitProps(props, ["greeting", "name", "age"]);
  console.log(local, others)
  return (
    <h3 {...others}>
      {local.greeting} {local.name} {local.age}
    </h3>
  );
}
复制代码

就很完美!

目录
相关文章
|
13天前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端框架
【10月更文挑战第34天】在数字化时代,后端开发如同一座桥梁,连接着用户界面与数据处理的两端。本文将通过Node.js这一轻量级、高效的平台,带领读者领略后端框架的魅力。我们将从基础概念出发,逐步深入到实战应用,最后探讨如何通过代码示例来巩固学习成果,使读者能够在理论与实践之间架起自己的桥梁。
|
16天前
|
算法 JavaScript 前端开发
垃圾回收机制对 JavaScript 性能的影响有哪些?
【10月更文挑战第29天】垃圾回收机制对JavaScript性能有着重要的影响。开发者需要了解不同垃圾回收算法的特点和性能开销,通过合理的代码优化和内存管理策略,来降低垃圾回收对性能的负面影响,提高JavaScript程序的整体性能。
|
1天前
|
缓存 监控 JavaScript
Vue.js 框架下的性能优化策略与实践
Vue.js 框架下的性能优化策略与实践
|
15天前
|
JavaScript 前端开发
利用事件循环提高 JavaScript 程序的性能
本文介绍了事件循环在JavaScript中的工作原理,以及如何通过合理利用事件循环来优化程序性能,包括异步操作、任务优先级和避免阻塞等技巧。
|
15天前
|
移动开发 前端开发 JavaScript
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
于辰在大学期间带领团队参考网易游戏官网的部分游戏页面,开发了一系列前端实训作品。项目包括首页、2021校园招聘页面和明日之后游戏页面,涉及多种特效实现,如动态图片切换和人物聚合效果。作品源码已上传至CSDN,视频效果可在CSDN预览。
24 0
前端实训,刚入门,我用原生技术(H5、C3、JS、JQ)手写【网易游戏】页面特效
|
19天前
|
JavaScript 中间件 API
Node.js进阶:Koa框架下的RESTful API设计与实现
【10月更文挑战第28天】本文介绍了如何在Koa框架下设计与实现RESTful API。首先概述了Koa框架的特点,接着讲解了RESTful API的设计原则,包括无状态和统一接口。最后,通过一个简单的博客系统示例,详细展示了如何使用Koa和koa-router实现常见的CRUD操作,包括获取、创建、更新和删除文章。
36 4
|
26天前
|
Web App开发 JavaScript 中间件
构建高效后端服务:Node.js与Express框架的完美结合
【10月更文挑战第21天】本文将引导你走进Node.js和Express框架的世界,探索它们如何共同打造一个高效、可扩展的后端服务。通过深入浅出的解释和实际代码示例,我们将一起理解这一组合的魅力所在,并学习如何利用它们来构建现代Web应用。
46 1
|
14天前
|
Web App开发 JavaScript 前端开发
构建高效后端服务:Node.js与Express框架的实践
【10月更文挑战第33天】在数字化时代的浪潮中,后端服务的效率和可靠性成为企业竞争的关键。本文将深入探讨如何利用Node.js和Express框架构建高效且易于维护的后端服务。通过实践案例和代码示例,我们将揭示这一组合如何简化开发流程、优化性能,并提升用户体验。无论你是初学者还是有经验的开发者,这篇文章都将为你提供宝贵的见解和实用技巧。
|
16天前
|
Web App开发 JavaScript 中间件
构建高效后端服务:Node.js与Express框架的融合之道
【10月更文挑战第31天】在追求快速、灵活和高效的后端开发领域,Node.js与Express框架的结合如同咖啡遇见了奶油——完美融合。本文将带你探索这一组合如何让后端服务搭建变得既轻松又充满乐趣,同时确保你的应用能够以光速运行。
24 0
|
JavaScript 前端开发 API
Vue.js入门指南:从基础到进阶,掌握现代JavaScript框架的核心概念与高级特性(2W字小白教程)
Vue.js入门指南:从基础到进阶,掌握现代JavaScript框架的核心概念与高级特性(2W字小白教程)
178 0
下一篇
无影云桌面