[英]LitElement: best practise (or best performance) when creating many custom style rules vs a couple of dynamic rules inside a tiny web component?
所以我正在開發一個非常小的 web 組件,作為更大設計系統的一部分。
我對 Web Components 的使用有點陌生,但我知道這個特定的 Web 組件可以在單個布局中多次使用。
這個 web 組件控制在傳入它的任何子組件周圍放置多少垂直空間。
該組件的解剖結構非常簡單:
import { LitElement, html, css, unsafeCSS, property, customElement } from 'lit-element';
export const spacingAmounts = {
'x-small': css`4px`,
'small': css`8px`,
'medium': css`12px`,
'large': css`16px`,
'x-large': css`20px`,
'2x-large': css`30px`,
'3x-large': css`40px`,
'4x-large': css`60px`,
'5x-large': css`90px`,
'6x-large': css`120px`,
};
const createSpacingStyleRules = (direction: 'top' | 'bottom') => {
return Object.keys(spacingAmounts).map(s => {
const amount = spacingAmounts[s];
return css`
:host([${unsafeCSS(direction)}="${unsafeCSS(s)}"]) {
margin-${unsafeCSS(direction)}: ${unsafeCSS(amount)};
}
`;
});
};
@customElement('gu-vertical-space')
export class GuVerticalSpace extends LitElement {
@property() top: string;
@property() bottom: string;
static get styles() {
const styles = [
css`
:host {
display: block;
}
`,
// ----------------------------------------------------------
// @TODO:
// test if it's better performance wise to either:
//
// 1 - generate a verbose list of static styles for
// each instance of gu-vertical-space
// or
// 2 - generate a tiny amount of styles on the fly,
// based on property inputs...
// ----------------------------------------------------------
// ...createSpacingStyleRules('top'),
// ...createSpacingStyleRules('bottom'),
];
return styles;
}
render() {
const styles = [];
if (this.top) {
styles.push(css`
:host([top="${unsafeCSS(this.top)}"]) {
margin-top: ${spacingAmounts[this.top]}
}
`);
}
if (this.bottom) {
styles.push(css`
:host([bottom="${unsafeCSS(this.bottom)}"]) {
margin-bottom: ${spacingAmounts[this.bottom]}
}
`);
}
return html`
<style>${styles}</style>
<slot></slot>
`;
}
}
這里有兩種方法可以將預定義的邊距量映射到 Web 組件主機的頂部或底部。
當前活躍的方法只是在渲染函數內動態生成一個<style>
塊,其中包含任何邊距量,由“頂部”或“底部”輸入屬性決定。
我正在考慮的另一種方法(盡管在 atm 中被注釋掉了) - 是靜態生成大量樣式規則 - 從而避免需要在 render() 函數中生成任何動態樣式的東西,這可能是一個反模式 - 如果我正確理解了lit-element 文檔。
也許我缺少一種更優雅的方法? 我傾向於當前的方法,只是因為它更容易理解 - 但對其他人的想法感到好奇!
正如 Alan 所建議的,這個問題的一個更簡單的解決方案是使用 css-variables。
基本上,只需在 connect() 生命周期事件中將輸入邊距量映射為 css 變量(或者,如果您認為道具在初始渲染后會發生變化,則進行渲染) - 並稱它為一天!
static get styles() {
return css`
:host {
display: block;
margin-top: var(--margin-top);
margin-bottom: var(--margin-bottom);
}
`;
}
connectedCallback() {
super.connectedCallback();
this.style.setProperty(
'--margin-top',
this.top
? spacingAmounts[this.top]
: 'unset'
);
this.style.setProperty(
'--margin-bottom',
this.bottom
? spacingAmounts[this.bottom]
: 'unset'
);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.