首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用SolidJS导入并呈现html元素

使用SolidJS导入并呈现html元素
EN

Stack Overflow用户
提问于 2022-10-18 08:23:27
回答 2查看 204关注 0票数 0

当我的应用程序加载时,它将调用后端以获得用户决定添加的组件的描述。

这些对象应该有一个函数来生成它们的html,以一个按钮为例:它将导出一个html()方法,该方法返回一个包含HTML文本的字符串:

代码语言:javascript
复制
const buttonText = "I'm a button"
export default {
  html() {
    return `<button>${buttonText}</button>`
  }
}

在前端,我将使用import语句加载上述按钮模块,并将其存储在JSON对象中,类似于插件管理器。

当需要呈现它时,我尝试使用Dynamic:

代码语言:javascript
复制
<For each={plugins()} fallback={<p>Loading...</p>}>{ plugin =>
  <div>
    <Dynamic component={plugin.module.html()}>
    </Dynamic>
  <div>
}</For>

但它落在DOMException: Failed to execute 'createElement' on 'Document': The tag name provided ('<button>I'm a button</button>') is not a valid name.身上

这是有意义的,因为它期待的是类似于"div"元素的东西,而不是像<button>I'm a button</button>这样的字符串。

在SolidJS中呈现HTML的正确方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-10-23 07:15:01

一个简单的解决方案就是像这样使用innerHTML

代码语言:javascript
复制
<For each={plugins()} fallback={<p>Loading...</p>}>
{ plugin =>
 <div innerHTML={plugin.module.html()}>
 <div>
}</For>

如果您需要更具有交互性的东西,可以使用templatecloneNode,这正是Solidjs通常编译代码的方式。下面是一个完整的例子。我在操场上创作的

代码语言:javascript
复制
import { render, template } from "solid-js/web";
import { For } from "solid-js";

function MakeButton() {
  const plugins = ["<button>Click me</button>"];

  const handleClick = () => {
    console.log("Clicked button");
  }

  const createElem = (el: string) => {
    const elem = template(el, 2);
    const ret = elem.cloneNode(true);
    if (ret.tagName === "BUTTON") {
      ret.onclick = handleClick;
    }
    return ret;
  }

  return (<>
    <For each={plugins} fallback={<div>Loading...</div>}>
      {plugin =>
        <div>{createElem(plugin)}</div>
      }
    </For>
  </>);
}

render(() => <MakeButton />, document.getElementById("app"));
票数 0
EN

Stack Overflow用户

发布于 2022-10-27 19:29:23

如果我正确地理解了您的问题,您将尝试导入一个常规的HTML元素并将其呈现在一个坚实的组件中,而不是简单的回答,就像其他表达式一样,将其放在花括号中。与React不同,Solid可以直接呈现HTML元素。

代码语言:javascript
复制
import { render } from "solid-js/web";
import { createSignal } from "solid-js";

const el = document.createElement('p');
el.innerHTML = 'Some Content';

function App() {
  return (
    <div>{el}</div>
  );
}

render(App, document.getElementById("app")!);

您不需要使用innerHTML属性,甚至不需要将其包装在JSX元素中:

代码语言:javascript
复制
const el = document.createElement('p');
el.innerHTML = 'Some Content';

function App() {
  return el;
}

你的问题很少有问题。html方法不是返回一个HTML元素,而是返回一个字符串:

代码语言:javascript
复制
const buttonText = "I'm a button"
export default {
  html() {
    return `<button>${buttonText}</button>`
  }
}

您可以通过返回一个实际元素来修复它。为了避免代码膨胀,我调用了导入的对象x,因为您可以从另一个模块导入任何变量:

代码语言:javascript
复制
const buttonText = "I'm a button";

const x = {
  html() {
    const el = document.createElement("button");
    el.innerText = buttonText;
    return el;
  },
};

function App() {
  return x.html();
}

如果使用x只是为了返回字符串,则可以完全省略它并导出元素本身:

代码语言:javascript
复制
const el = document.createElement("button");
el.innerText = buttonText;

export default el;

作为另一种选择,您可以返回字符串并使用innerHTML属性为您提供DOM呈现。您可以自己创建元素:

代码语言:javascript
复制
const el = document.createElement('div');
el.innerHTML = x.html();

或者让实心帮你做:

代码语言:javascript
复制
const txt = "<button>I'm a button</button>";

function App() {
  return <div innerHTML={txt}></div>
}

无论哪种方式,它都与Solid无关,当分配给元素的innerHTML时,将字符串呈现为HTML元素是浏览器的特性。实际上,它是Solid的template函数内部使用的。

顺便提一句,Solid使用克隆方法高效地呈现多个元素,如果您不使用大量元素来呈现大型HTML文本,createElement会更好,因为它更干净、更快。

“动态加载组件”指的是完全不同的东西,组件也是如此。动态组件意味着呈现的输出绑定到变量而不是条件:

代码语言:javascript
复制
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 [selected, setSelected] = createSignal('red');

const options = {
  red: RedThing,
  green: GreenThing,
  blue: BlueThing
}

<Dynamic component={options[selected()]} />

您仍然需要传递组件,而不是字符串。包含有效HTML文本的字符串不是JSX组件。

最好用简单的术语来表达我们的问题,并避免使用技术术语,因为它真的很难理解。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74107879

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档