将 HTML 和 CSS 与 Javascript 点亮元素分开
Seperating HTML and CSS from Javascript Lit Element
我们正在使用 Lit Element,我们的组件文件变得相当大,因为我们必须在 .js 文件中编写样式和 html。有没有办法将它们拆分成单独的文件,然后将它们导入到我们的组件中?这样做的最佳方法是什么? HTML 和 CSS 尤其让我们的工作流程变得困难,因为我们的文件变得过于臃肿。
更新:Supersharp 的建议帮助我分离了 CSS 和 html 模板,但我在绑定 html 模板时遇到问题具有指定的属性。我有一个服务文件,它正在对我指定的文件发出 XML 请求,我将它们导入到我的组件文件中。这是我的组件:
import { LitElement, html} from '@polymer/lit-element';
import HtmlLoader from './Service/HtmlLoader';
class TestAnimatedButtonElement extends LitElement {
static get properties() {
return {
_text: {
type: String
}
}
}
constructor() {
super();
this.htmlTemplate = HtmlLoader.prototype.getHtmlTemplate('/src/Components/ExampleElements/test-animated-button-element.html');
}
render(){
this.htmlTemplate.then( template => this.shadowRoot.innerHTML = template)
return html( [this.htmlTemplate] );
}
handleButton(e) {
//e.preventDefault();
console.log('Button pressed');
}
}
customElements.define('test-animated-button-element', TestAnimatedButtonElement);
这是我的 html 文件:
<link rel="stylesheet" href="src/Components/animatedButton/animated-button-element.css"/>
<a href="#" class="btn btn--white btn--animated" @click="${(e) => this.handleButton(e)}">${this._text}</a>
这是我用来制作 XMLHttpRequest:
的服务文件
export default class HtmlLoader {
xhrCall(url){
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
getHtmlTemplate(url) {
return this.xhrCall(url);
}
}
您可以分别导入 CSS 和 HTML 部分。
CSS
在 HTML 代码中使用 <link rel="stylesheet">
元素。
HTML
您可以使用 HTML Imports(已弃用)或 XMLHttpRequest 或 fetch(),如 post 关于 的解释。
更新
有了 XMLHtpRequest
,您将在 Promise 中得到答案。
render(){
this.htmlTemplate.then( template =>
this.shadowRoot.innerHTML = template
)
}
这是 ES 模块的缺点,这就是为什么 Google 推动 HTML 导入这么久,尽管其他浏览器供应商坚决反对它们。
您可以将 CSS 和 JS 分开,但如果您在 运行 时获取它们,则会向浏览器添加额外的往返行程。特别是你的模板是异步检索的,如果你等待它们,你会在你做的时候阻塞主 JS 线程,如果你 await
它们你会破坏 lit-element
因为它期望根模板同步。
您可以(但不应该)使用until
:
import { until } from 'lit-html/directives/until';
...
render(){
return html`until(
this.loadTemplate(
'/src/Components/ExampleElements/test-animated-button-element.html',
this.foo,
this.bar), html`Loading...`)`;
}
async loadTemplate(path, ...parts) {
// You're using templates you can use fetch, instead of XMLHttpRequest
const r = await fetch(path, { method: 'GET', credentials: 'same-origin' });
if(r.ok)
return html(await r.text(), parts);
return html`Not Found: ${path}`
}
但是,我注意到您使用的是裸模块(即开头没有 .
结尾没有 .js
),因此您不能将此文件直接提供给浏览器(none 还可以处理裸模块)。简而言之:您必须拥有可以转动的东西:
import { LitElement, html} from '@polymer/lit-element';
进入:
import { LitElement, html } from '../../node_modules/@polymer/lit-element/lit-element.js';
或者将它们捆绑到一个文件中。鉴于您正在这样做,为什么不让您的捆绑器(Webpack、RollupJS、Browserify 等)在 构建时间 将您的 CSS 和 HTML 导入到文件中?
最后,使用这些解决方案中的任何一个,您都会失去写入时间部分<->html 关系,这对 CSS 无关紧要,但会使 HTML 部分变得更重要更难 develop/maintain。对于像 lit 这样的库,你 想要 你的 HTML 在你的 JS 中,出于与 JSX/React/Preact 工作得很好的相同原因。如果您的文件太大,那么我认为解决方案不是将它们拆分为 JS/CSS/HTML - 而是将它们拆分为更多组件。
因此,例如,假设您有一个巨大的 <product-detail>
控件...
不要
- 产品-detail.js
- 产品-detail.html
- 产品-detail.css
做
- 产品-detail.js
- 产品详情-dimensions.js
- 产品详情-specs.js
- 产品详情-parts.js
- 产品详情-preview.js
- 等等
分解每个组件以完成特定任务。 lit-element
的全部要点是让所有这些尽可能简单地创建,而你需要很多小的、独立的组件。
我们正在使用 Lit Element,我们的组件文件变得相当大,因为我们必须在 .js 文件中编写样式和 html。有没有办法将它们拆分成单独的文件,然后将它们导入到我们的组件中?这样做的最佳方法是什么? HTML 和 CSS 尤其让我们的工作流程变得困难,因为我们的文件变得过于臃肿。
更新:Supersharp 的建议帮助我分离了 CSS 和 html 模板,但我在绑定 html 模板时遇到问题具有指定的属性。我有一个服务文件,它正在对我指定的文件发出 XML 请求,我将它们导入到我的组件文件中。这是我的组件:
import { LitElement, html} from '@polymer/lit-element';
import HtmlLoader from './Service/HtmlLoader';
class TestAnimatedButtonElement extends LitElement {
static get properties() {
return {
_text: {
type: String
}
}
}
constructor() {
super();
this.htmlTemplate = HtmlLoader.prototype.getHtmlTemplate('/src/Components/ExampleElements/test-animated-button-element.html');
}
render(){
this.htmlTemplate.then( template => this.shadowRoot.innerHTML = template)
return html( [this.htmlTemplate] );
}
handleButton(e) {
//e.preventDefault();
console.log('Button pressed');
}
}
customElements.define('test-animated-button-element', TestAnimatedButtonElement);
这是我的 html 文件:
<link rel="stylesheet" href="src/Components/animatedButton/animated-button-element.css"/>
<a href="#" class="btn btn--white btn--animated" @click="${(e) => this.handleButton(e)}">${this._text}</a>
这是我用来制作 XMLHttpRequest:
的服务文件export default class HtmlLoader {
xhrCall(url){
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onload = () => resolve(xhr.responseText);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
getHtmlTemplate(url) {
return this.xhrCall(url);
}
}
您可以分别导入 CSS 和 HTML 部分。
CSS
在 HTML 代码中使用 <link rel="stylesheet">
元素。
HTML
您可以使用 HTML Imports(已弃用)或 XMLHttpRequest 或 fetch(),如 post 关于
更新
有了 XMLHtpRequest
,您将在 Promise 中得到答案。
render(){
this.htmlTemplate.then( template =>
this.shadowRoot.innerHTML = template
)
}
这是 ES 模块的缺点,这就是为什么 Google 推动 HTML 导入这么久,尽管其他浏览器供应商坚决反对它们。
您可以将 CSS 和 JS 分开,但如果您在 运行 时获取它们,则会向浏览器添加额外的往返行程。特别是你的模板是异步检索的,如果你等待它们,你会在你做的时候阻塞主 JS 线程,如果你 await
它们你会破坏 lit-element
因为它期望根模板同步。
您可以(但不应该)使用until
:
import { until } from 'lit-html/directives/until';
...
render(){
return html`until(
this.loadTemplate(
'/src/Components/ExampleElements/test-animated-button-element.html',
this.foo,
this.bar), html`Loading...`)`;
}
async loadTemplate(path, ...parts) {
// You're using templates you can use fetch, instead of XMLHttpRequest
const r = await fetch(path, { method: 'GET', credentials: 'same-origin' });
if(r.ok)
return html(await r.text(), parts);
return html`Not Found: ${path}`
}
但是,我注意到您使用的是裸模块(即开头没有 .
结尾没有 .js
),因此您不能将此文件直接提供给浏览器(none 还可以处理裸模块)。简而言之:您必须拥有可以转动的东西:
import { LitElement, html} from '@polymer/lit-element';
进入:
import { LitElement, html } from '../../node_modules/@polymer/lit-element/lit-element.js';
或者将它们捆绑到一个文件中。鉴于您正在这样做,为什么不让您的捆绑器(Webpack、RollupJS、Browserify 等)在 构建时间 将您的 CSS 和 HTML 导入到文件中?
最后,使用这些解决方案中的任何一个,您都会失去写入时间部分<->html 关系,这对 CSS 无关紧要,但会使 HTML 部分变得更重要更难 develop/maintain。对于像 lit 这样的库,你 想要 你的 HTML 在你的 JS 中,出于与 JSX/React/Preact 工作得很好的相同原因。如果您的文件太大,那么我认为解决方案不是将它们拆分为 JS/CSS/HTML - 而是将它们拆分为更多组件。
因此,例如,假设您有一个巨大的 <product-detail>
控件...
不要
- 产品-detail.js
- 产品-detail.html
- 产品-detail.css
做
- 产品-detail.js
- 产品详情-dimensions.js
- 产品详情-specs.js
- 产品详情-parts.js
- 产品详情-preview.js
- 等等
分解每个组件以完成特定任务。 lit-element
的全部要点是让所有这些尽可能简单地创建,而你需要很多小的、独立的组件。