当我的应用程序加载时,它将调用后端以获得用户决定添加的组件的描述。
这些对象应该有一个函数来生成它们的html,以一个按钮为例:它将导出一个html()方法,该方法返回一个包含HTML文本的字符串:
const buttonText = "I'm a button"
export default {
html() {
return `<button>${buttonText}</button>`
}
}在前端,我将使用import语句加载上述按钮模块,并将其存储在JSON对象中,类似于插件管理器。
当需要呈现它时,我尝试使用Dynamic:
<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的正确方法是什么?
发布于 2022-10-23 07:15:01
一个简单的解决方案就是像这样使用innerHTML:
<For each={plugins()} fallback={<p>Loading...</p>}>
{ plugin =>
<div innerHTML={plugin.module.html()}>
<div>
}</For>如果您需要更具有交互性的东西,可以使用template和cloneNode,这正是Solidjs通常编译代码的方式。下面是一个完整的例子。我在操场上创作的。
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"));发布于 2022-10-27 19:29:23
如果我正确地理解了您的问题,您将尝试导入一个常规的HTML元素并将其呈现在一个坚实的组件中,而不是简单的回答,就像其他表达式一样,将其放在花括号中。与React不同,Solid可以直接呈现HTML元素。
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元素中:
const el = document.createElement('p');
el.innerHTML = 'Some Content';
function App() {
return el;
}你的问题很少有问题。html方法不是返回一个HTML元素,而是返回一个字符串:
const buttonText = "I'm a button"
export default {
html() {
return `<button>${buttonText}</button>`
}
}您可以通过返回一个实际元素来修复它。为了避免代码膨胀,我调用了导入的对象x,因为您可以从另一个模块导入任何变量:
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只是为了返回字符串,则可以完全省略它并导出元素本身:
const el = document.createElement("button");
el.innerText = buttonText;
export default el;作为另一种选择,您可以返回字符串并使用innerHTML属性为您提供DOM呈现。您可以自己创建元素:
const el = document.createElement('div');
el.innerHTML = x.html();或者让实心帮你做:
const txt = "<button>I'm a button</button>";
function App() {
return <div innerHTML={txt}></div>
}无论哪种方式,它都与Solid无关,当分配给元素的innerHTML时,将字符串呈现为HTML元素是浏览器的特性。实际上,它是Solid的template函数内部使用的。
顺便提一句,Solid使用克隆方法高效地呈现多个元素,如果您不使用大量元素来呈现大型HTML文本,createElement会更好,因为它更干净、更快。
“动态加载组件”指的是完全不同的东西,组件也是如此。动态组件意味着呈现的输出绑定到变量而不是条件:
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组件。
最好用简单的术语来表达我们的问题,并避免使用技术术语,因为它真的很难理解。
https://stackoverflow.com/questions/74107879
复制相似问题