SolidJs之绑定

715 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第9天,点击查看活动详情

绑定事件

在Solid中,所有的事件都会以on为前缀。事件和响应式数据不一样,只需要在初始化绑定即可。所有的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'));

该例子很好地展示了solid的绑定事件的写法。主要就是用到了原生的js方法mouseMove事件,在其前面添加on前缀。

样式

solid中的style属性接受样式字符串或者对象。但是需要采用破折号的形式,如background-color而不是backgroundColor。 例子:

<div style={{
      color: `rgb(${num()}, 180, ${num()})`,
      "font-weight": 800,
      "font-size": `${num()}px`}}
    >
      Some Text
    </div>

classList

solid同时支持class和ClassName来设置元素的className属性,同时也支持JSX属性,动态的对class进行添加和移除操作,是一个布尔表达式。当为true时应用该class,为false时该class被移除。 例子:

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

import "./style.css";

function App() {
  const [current, setCurrent] = createSignal("foo");

  return <>
    <button
	   classList={{selected: current() === 'foo'}}
	   onClick={() => setCurrent('foo')}
    >foo</button>
    <button
	    classList={{selected: current() === 'bar'}}
	    onClick={() => setCurrent('bar')}
    >bar</button>
    <button
	    classList={{selected: current() === 'baz'}}
	    onClick={() => setCurrent('baz')}
    >baz</button>
  </>;
}

render(() => <App />, document.getElementById('app'));

该段代码使用current的值去控制三个的背景颜色的变化。

Ref

在solid中,你可以通过ref赋值拿到元素的引用,像这样:

<div ref={myDiv}>My Element</div>;

赋值行为是在元素创建时,在dom被追加前发生的。

Ref转发

在很多情况下,我们需要将组件暴露给其它组件,如给父组件使用,因此我们还是需要使用ref属性来实现。只需要在父组件里面显示传入ref属性。 如:

App.jsx
function App() {
 let canvas;

   onCleanup(() => cancelAnimationFrame(frame));
 });

 return <Canvas ref={canvas} />;
}

// cavas.jsx
export default function Canvas(props) {
 return <canvas ref={props.ref} width="256" height="256" />;
}

扩展

为了避免传多个属性值,可以使用扩展运算符显示传入,子组件正常接收即可。

<Info {...pkg} />

指令

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

如:

//mian.jsx
import { render } from "solid-js/web";
import { createSignal, Show } from "solid-js";
import clickOutside from "./click-outside";
import "./style.css";

function App() {
  const [show, setShow] = createSignal(false);

  return (
    <Show
      when={show()}
      fallback={<button onClick={(e) => setShow(true)}>Open Modal</button>}
    >
      <div class="modal" use:clickOutside={() => setShow(false)}>
        Some Modal
      </div>
    </Show>
  );
}

render(() => <App />, document.getElementById("app"));
//click-outside.js
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.body.removeEventListener("click", onClick));
}


在这个例子中,我们将为点击外部行为制作一个简单的封装函数来关闭弹出窗口或模态框。首先,我们需要在我们的元素上导入并使用我们的 clickOutside 指令。