內建指令
指令是函數,可以藉由自訂表達式的渲染方式來擴展 Lit。Lit 包含許多內建指令,可協助處理各種渲染需求
指令 | 摘要 |
---|---|
樣式 | |
根據物件將一組類別指派給元素。 | |
根據物件將一組樣式屬性設定給元素。 | |
迴圈與條件式 | |
根據條件渲染兩個模板之一。 | |
根據鍵值渲染多個模板之一。 | |
使用函數轉換可迭代物件。 | |
將可迭代物件中的值渲染到 DOM 中,並可選擇使用鍵控來啟用資料差異化和 DOM 穩定性。 | |
將可迭代物件中的值與串接器值交錯。 | |
建立序列中的數字可迭代物件,對於迭代特定次數很有用。 | |
如果值已定義,則設定屬性,如果未定義則移除屬性。 | |
快取與變更偵測 | |
在變更模板時快取渲染的 DOM,而不是捨棄 DOM。 | |
將可渲染的值與唯一鍵關聯,如果鍵變更,則強制重新渲染 DOM。 | |
僅在其中一個相依性變更時重新評估模板。 | |
如果屬性或屬性與即時 DOM 值不同,而不是與上次渲染的值不同,則設定屬性或屬性。 | |
參照渲染的 DOM | |
取得對模板中渲染的元素的參照。 | |
渲染特殊值 | |
渲染 | |
將字串渲染為 HTML 而不是文字。 | |
將字串渲染為 SVG 而不是文字。 | |
非同步渲染 | |
渲染預留位置內容,直到一或多個 Promise 解析為止。 | |
將 | |
將 |
僅捆綁您使用的內容。 這些之所以稱為「內建」指令,是因為它們是 Lit 套件的一部分。但每個指令都是一個獨立的模組,因此您的應用程式只會捆綁您匯入的指令。
您也可以建立自己的指令。如需更多資訊,請參閱自訂指令。
classMap
「classMap」的永久連結根據物件將一組類別設定給元素。
匯入 |
|
簽名 |
|
可用位置 |
|
classMap
指令使用 element.classList
API,根據使用者傳遞的物件來有效率地將類別新增和移除到元素。物件中的每個鍵都會被視為類別名稱,如果與鍵關聯的值為真值,則會將該類別新增到元素。在後續渲染時,先前設定為偽值或不再位於物件中的任何類別都會被移除。
@customElement('my-element')
class MyElement extends LitElement {
@property({type: Boolean})
enabled = false;
render() {
const classes = { enabled: this.enabled, hidden: false };
return html`<div class=${classMap(classes)}>Classy text</div>`;
}
}
class MyElement extends LitElement {
static properties = {
enabled: {type: Boolean},
};
constructor() {
super();
this.enabled = false;
}
render() {
const classes = { enabled: this.enabled, hidden: false };
return html`<div class=${classMap(classes)}>Classy text</div>`;
}
}
customElements.define('my-element', MyElement);
classMap
必須是 class
屬性中唯一的表達式,但它可以與靜態值結合使用
html`<div class="my-widget ${classMap(dynamicClasses)}">Static and dynamic</div>`;
在遊樂場中進一步探索 classMap
。
styleMap
「styleMap」的永久連結根據物件將一組樣式屬性設定給元素。
匯入 |
|
簽名 |
|
可用位置 |
|
styleMap
指令使用 element.style
API,根據使用者傳遞的物件來有效率地將內嵌樣式新增和移除到元素。物件中的每個鍵都會被視為樣式屬性名稱,值則會被視為該屬性的值。在後續渲染時,先前設定為未定義或 null
的任何樣式屬性都會被移除(設定為 null
)。
@customElement('my-element')
class MyElement extends LitElement {
@property({type: Boolean})
enabled = false;
render() {
const styles = { backgroundColor: this.enabled ? 'blue' : 'gray', color: 'white' };
return html`<p style=${styleMap(styles)}>Hello style!</p>`;
}
}
class MyElement extends LitElement {
static properties = {
enabled: {type: Boolean},
};
constructor() {
super();
this.enabled = false;
}
render() {
const styles = { backgroundColor: this.enabled ? 'blue' : 'gray', color: 'white' };
return html`<p style=${styleMap(styles)}>Hello style!</p>`;
}
}
customElements.define('my-element', MyElement);
對於包含破折號的 CSS 屬性,您可以使用駝峰式對應寫法,或將屬性名稱放在引號中。例如,您可以將 CSS 屬性 font-family
寫成 fontFamily
或 'font-family'
{ fontFamily: 'roboto' }
{ 'font-family': 'roboto' }
若要參照 CSS 自訂屬性(例如 --custom-color
),請將整個屬性名稱放在引號中
{ '--custom-color': 'steelblue' }
styleMap
必須是 style
屬性中唯一的表達式,但它可以與靜態值結合使用
html`<p style="color: white; ${styleMap(moreStyles)}">More styles!</p>`;
在遊樂場中進一步探索 styleMap
。
迴圈與條件式
「迴圈與條件式」的永久連結when
「when」的永久連結根據條件渲染兩個模板之一。
匯入 |
|
簽名 |
|
可用位置 | 任何 |
當 condition
為 true 時,傳回呼叫 trueCase()
的結果,否則,如果已定義 falseCase
,則傳回呼叫 falseCase()
的結果。
這是三元表達式的便利包裝函式,讓您在沒有 else 的情況下,以更簡潔的方式撰寫內嵌條件式。
class MyElement extends LitElement {
render() {
return html`
${when(this.user, () => html`User: ${this.user.username}`, () => html`Sign In...`)}
`;
}
}
choose
「choose」的永久連結根據將給定的 value
與案例比對,從案例列表中選擇並評估模板函數。
匯入 |
|
簽名 |
|
可用位置 | 任何 |
案例結構為 [caseValue, func]
。value
會透過嚴格相等與 caseValue
比對。會選取第一個符合的項目。案例值可以是任何類型,包括原始值、物件和符號。
這類似於 switch 陳述式,但是以表達式的方式,而且沒有貫穿。
class MyElement extends LitElement {
render() {
return html`
${choose(this.section, [
['home', () => html`<h1>Home</h1>`],
['about', () => html`<h1>About</h1>`]
],
() => html`<h1>Error</h1>`)}
`;
}
}
map
「map」的永久連結傳回包含呼叫 f(value)
在 items
中每個值上的結果的可迭代物件。
匯入 |
|
簽名 |
|
可用位置 | 任何 |
map()
是 for/of 迴圈的簡單包裝函式,讓您在表達式中更輕鬆地使用可迭代物件。map()
一律會就地更新任何建立的 DOM - 它不會執行任何差異化或 DOM 移動。如果您需要該功能,請參閱repeat。map()
比 repeat()
更小更快,因此如果您不需要差異化和 DOM 穩定性,請優先使用 map()
。
class MyElement extends LitElement {
render() {
return html`
<ul>
${map(items, (i) => html`<li>${i}</li>`)}
</ul>
`;
}
}
repeat
「repeat」的永久連結將可迭代物件中的值渲染到 DOM 中,並可選擇使用鍵控來啟用資料差異化和 DOM 穩定性。
匯入 |
|
簽名 |
|
可用位置 | 子表達式 |
重複從可迭代物件產生的一系列值(通常是 TemplateResults
),並在可迭代物件變更時有效率地更新這些項目。當提供 keyFn
時,會在更新之間透過在需要時移動產生的 DOM 來維護鍵到 DOM 的關聯性,而且通常是使用 repeat
的最有效率方式,因為它會針對插入和移除執行最少的非必要工作。
如果您未使用鍵函數,則應該考慮使用 map()
。
@customElement('my-element')
class MyElement extends LitElement {
@property()
items: Array<{id: number, name: string}> = [];
render() {
return html`
<ul>
${repeat(this.items, (item) => item.id, (item, index) => html`
<li>${index}: ${item.name}</li>`)}
</ul>
`;
}
}
class MyElement extends LitElement {
static properties = {
items: {},
};
constructor() {
super();
this.items = [];
}
render() {
return html`
<ul>
${repeat(this.items, (item) => item.id, (item, index) => html`
<li>${index}: ${item.name}</li>`)}
</ul>
`;
}
}
customElements.define('my-element', MyElement);
如果未提供 keyFn
,repeat
的運作方式會類似於將項目對應到值的簡單對應,且 DOM 會針對可能不同的項目重複使用。
如需何時使用 repeat
以及何時使用標準 JavaScript 流程控制的討論,請參閱何時使用 map 或 repeat。
在遊樂場中進一步探索 repeat
。
join
「join」的永久連結傳回包含 items
中與 joiner
值交錯的值的可迭代物件。
匯入 |
|
簽名 |
|
可用位置 | 任何 |
class MyElement extends LitElement {
render() {
return html`
${join(
map(menuItems, (i) => html`<a href=${i.href}>${i.label}</a>`),
html`<span class="separator">|</span>`
)}
`;
}
}
range
「range」的永久連結傳回從 start
到 end
(不含)以 step
遞增的整數可迭代物件。
匯入 |
|
簽名 |
|
可用位置 | 任何 |
class MyElement extends LitElement {
render() {
return html`
${map(range(8), (i) => html`${i + 1}`)}
`;
}
}
ifDefined
「ifDefined」的永久連結如果值已定義,則設定屬性,如果未定義則移除屬性。
匯入 |
|
簽名 |
|
可用位置 | 屬性表達式 |
對於 AttributePart,如果值已定義,則設定屬性;如果值未定義(undefined
或 null
),則移除屬性。對於其他部分類型,此指令不會執行任何動作。
當單一屬性值中存在多個表達式時,如果任何表達式使用 ifDefined
且評估為 undefined
/null
,則該屬性將被移除。這對於設定 URL 屬性特別有用,當 URL 的必要部分未定義時,不應設定該屬性以防止 404 錯誤。
@customElement('my-element')
class MyElement extends LitElement {
@property()
filename: string | undefined = undefined;
@property()
size: string | undefined = undefined;
render() {
// src attribute not rendered if either size or filename are undefined
return html`<img src="/images/${ifDefined(this.size)}/${ifDefined(this.filename)}">`;
}
}
class MyElement extends LitElement {
static properties = {
filename: {},
size: {},
};
constructor() {
super();
this.filename = undefined;
this.size = undefined;
}
render() {
// src attribute not rendered if either size or filename are undefined
return html`<img src="/images/${ifDefined(this.size)}/${ifDefined(this.filename)}">`;
}
}
customElements.define('my-element', MyEleent);
在遊樂場中進一步探索 ifDefined
。
快取與變更偵測
連結至「快取和變更偵測」cache
連結至「快取」當變更模板時,快取已渲染的 DOM,而不是丟棄 DOM。當頻繁切換大型模板時,您可以使用此指令來優化渲染效能。
匯入 |
|
簽名 |
|
可用位置 | 子表達式 |
當傳遞給 cache
的值在一個或多個 TemplateResult
之間變更時,當給定模板的已渲染 DOM 節點未使用時,它們會被快取。當模板變更時,指令會快取目前的 DOM 節點,然後切換到新值,並在切換回先前渲染的值時從快取還原它們,而不是重新建立 DOM 節點。
const detailView = (data) => html`<div>...</div>`;
const summaryView = (data) => html`<div>...</div>`;
@customElement('my-element')
class MyElement extends LitElement {
@property()
data = {showDetails: true, /*...*/ };
render() {
return html`${cache(this.data.showDetails
? detailView(this.data)
: summaryView(this.data)
)}`;
}
}
const detailView = (data) => html`<div>...</div>`;
const summaryView = (data) => html`<div>...</div>`;
class MyElement extends LitElement {
static properties = {
data: {},
};
constructor() {
super();
this.data = {showDetails: true, /*...*/ };
}
render() {
return html`${cache(this.data.showDetails
? detailView(this.data)
: summaryView(this.data)
)}`;
}
}
customElements.define('my-element', MyElement);
當 Lit 重新渲染模板時,它只會更新修改的部分:它不會建立或移除任何超出必要的 DOM。但是,當您從一個模板切換到另一個模板時,Lit 會移除舊的 DOM 並渲染新的 DOM 樹。
cache
指令會快取給定表達式和輸入模板所產生的 DOM。在上面的範例中,它會快取 summaryView
和 detailView
模板的 DOM。當您從一個視圖切換到另一個視圖時,Lit 會交換新視圖的快取版本,並使用最新資料更新它。當這些視圖頻繁切換時,這可以提高渲染效能。
在遊樂場中進一步探索 cache
。
keyed
連結至「鍵控」將可渲染的值與唯一鍵關聯。當鍵變更時,即使該值(例如模板)相同,也會在渲染下一個值之前移除並處置先前的 DOM。
匯入 |
|
簽名 |
|
可用位置 | 任何表達式 |
當您渲染有狀態的元素,並且需要確保當某些關鍵資料變更時清除元素的所有狀態時,keyed
非常有用。它本質上選擇退出 Lit 的預設 DOM 重用策略。
如果您需要強制使用新元素進行「進入」或「退出」動畫,keyed
在某些動畫情況下也很有用。
@customElement('my-element')
class MyElement extends LitElement {
@property()
userId: string = '';
render() {
return html`
<div>
${keyed(this.userId, html`<user-card .userId=${this.userId}></user-card>`)}
</div>`;
}
}
class MyElement extends LitElement {
static properties = {
userId: {},
};
constructor() {
super();
this.userId = '';
}
render() {
return html`
<div>
${keyed(this.userId, html`<user-card .userId=${this.userId}></user-card>`)}
</div>`;
}
}
customElements.define('my-element', MyElement);
guard
連結至「保護」僅當其依賴項之一變更時才重新評估模板,透過防止不必要的工作來優化渲染效能。
匯入 |
|
簽名 |
|
可用位置 | 任何表達式 |
渲染 valueFn
返回的值,並且僅當依賴項之一變更身份時才重新評估 valueFn
。
其中
dependencies
是要監視變更的值陣列。valueFn
是一個返回可渲染值的函式。
guard
在使用不可變資料模式時非常有用,可以防止在資料更新之前進行昂貴的工作。
@customElement('my-element')
class MyElement extends LitElement {
@property()
value: string = '';
render() {
return html`
<div>
${guard([this.value], () => calculateSHA(this.value))}
</div>`;
}
}
class MyElement extends LitElement {
static properties = {
value: {},
};
constructor() {
super();
this.value = '';
}
render() {
return html`
<div>
${guard([this.value], () => calculateSHA(this.value))}
</div>`;
}
}
customElements.define('my-element', MyElement);
在這種情況下,只有當 value
屬性變更時,才會執行昂貴的 calculateSHA
函式。
在遊樂場中進一步探索 guard
。
live
連結至「即時」如果屬性或屬性與即時 DOM 值不同,而不是與上次渲染的值不同,則設定屬性或屬性。
匯入 |
|
簽名 |
|
可用位置 | 屬性或屬性表達式 |
在決定是否更新值時,會將表達式值與即時 DOM 值進行比較,而不是與 Lit 的預設行為(與上次設定的值進行比較)進行比較。
這適用於 DOM 值可能從 Lit 外部變更的情況。例如,當使用表達式設定 <input>
元素的 value
屬性、可編輯內容元素的文字或變更自身屬性或屬性的自訂元素時。
在這些情況下,如果 DOM 值變更,但透過 Lit 表達式設定的值沒有變更,Lit 將不會知道要更新 DOM 值,並會保持原樣。如果這不是您想要的—如果您想要無論如何都使用綁定的值覆寫 DOM 值—請使用 live()
指令。
@customElement('my-element')
class MyElement extends LitElement {
@property()
data = {value: 'test'};
render() {
return html`<input .value=${live(this.data.value)}>`;
}
}
class MyElement extends LitElement {
static properties = {
data: {},
};
constructor() {
super();
this.data = {value: 'test'};
}
render() {
return html`<input .value=${live(this.data.value)}>`;
}
}
customElements.define('my-element', MyElement);
live()
對即時 DOM 值執行嚴格的相等性檢查,如果新值等於即時值,則不執行任何操作。這表示當表達式會導致類型轉換時,不應使用 live()
。如果您在屬性表達式中使用 live()
,請確保只傳入字串,否則表達式會在每次渲染時更新。
在遊樂場中進一步探索 live
。
渲染特殊值
連結至「渲染特殊值」templateContent
連結至「templateContent」渲染 <template>
元素的內容。
匯入 |
|
簽名 |
|
可用位置 | 子表達式 |
Lit 模板在 Javascript 中編碼,因此它們可以嵌入使其動態化的 Javascript 表達式。如果您有一個靜態 HTML <template>
,需要將其包含在 Lit 模板中,您可以使用 templateContent
指令來複製模板內容並將其包含在 Lit 模板中。只要模板元素參考在渲染之間沒有變更,後續的渲染將不會執行任何操作。
請注意,模板內容應由開發人員控制,且不得使用不受信任的字串建立。不受信任的內容範例包括查詢字串參數和來自使用者輸入的值。使用此指令渲染的不受信任的模板可能會導致跨網站指令碼 (XSS) 漏洞。
const templateEl = document.querySelector('template#myContent') as HTMLTemplateElement;
@customElement('my-element')
class MyElement extends LitElement {
render() {
return html`
Here's some content from a template element:
${templateContent(templateEl)}`;
}
}
const templateEl = document.querySelector('template#myContent');
class MyElement extends LitElement {
render() {
return html`
Here's some content from a template element:
${templateContent(templateEl)}`;
}
}
customElements.define('my-element', MyElement);
在遊樂場中進一步探索 templateContent
。
unsafeHTML
連結至「unsafeHTML」將字串渲染為 HTML 而不是文字。
匯入 |
|
簽名 |
|
可用位置 | 子表達式 |
Lit 模板語法的一個關鍵功能是,只有源自模板字面值的字串才會被解析為 HTML。由於模板字面值只能在受信任的腳本檔案中撰寫,因此這可以作為防止 XSS 攻擊注入不受信任 HTML 的自然防護措施。但是,在某些情況下,可能需要在 Lit 模板中渲染非源自腳本檔案的 HTML,例如從資料庫擷取的受信任 HTML 內容。unsafeHTML
指令會將此類字串解析為 HTML 並將其渲染到 Lit 模板中。
請注意,傳遞給 unsafeHTML
的字串必須由開發人員控制,且不得包含不受信任的內容。不受信任的內容範例包括查詢字串參數和來自使用者輸入的值。
使用此指令渲染的不受信任的內容可能會導致跨網站指令碼 (XSS)、CSS 注入、資料外洩等漏洞。unsafeHTML
使用 innerHTML
來解析 HTML 字串,因此安全性隱含與 innerHTML
相同,如 MDN 文件中所述。
const markup = '<h3>Some HTML to render.</h3>';
@customElement('my-element')
class MyElement extends LitElement {
render() {
return html`
Look out, potentially unsafe HTML ahead:
${unsafeHTML(markup)}
`;
}
}
const markup = '<h3>Some HTML to render.</h3>';
class MyElement extends LitElement {
render() {
return html`
Look out, potentially unsafe HTML ahead:
${unsafeHTML(markup)}
`;
}
}
customElements.define('my-element', MyElement);
在遊樂場中進一步探索 unsafeHTML
。
unsafeSVG
連結至「unsafeSVG」將字串渲染為 SVG 而不是文字。
匯入 |
|
簽名 |
|
可用位置 | 子表達式 |
與unsafeHTML
類似,在某些情況下,可能需要在 Lit 模板中渲染非源自腳本檔案的 SVG 內容,例如從資料庫擷取的受信任 SVG 內容。unsafeSVG
指令會將此類字串解析為 SVG 並將其渲染到 Lit 模板中。
請注意,傳遞給 unsafeSVG
的字串必須由開發人員控制,且不得包含不受信任的內容。不受信任的內容範例包括查詢字串參數和來自使用者輸入的值。使用此指令渲染的不受信任的內容可能會導致跨網站指令碼 (XSS) 漏洞。
const svg = '<circle cx="50" cy="50" r="40" fill="red" />';
@customElement('my-element')
class MyElement extends LitElement {
render() {
return html`
Look out, potentially unsafe SVG ahead:
<svg width="40" height="40" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" version="1.1">
${unsafeSVG(svg)}
</svg> `;
}
}
const svg = '<circle cx="50" cy="50" r="40" fill="red" />';
class MyElement extends LitElement {
render() {
return html`
Look out, potentially unsafe SVG ahead:
<svg width="40" height="40" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg" version="1.1">
${unsafeSVG(svg)}
</svg> `;
}
}
customElements.define('my-element', MyElement);
在遊樂場中進一步探索 unsafeSVG
。
參照渲染的 DOM
連結至「參考已渲染的 DOM」ref
連結至「ref」擷取對渲染到 DOM 中的元素的參考。
匯入 |
|
簽名 |
|
可用位置 | 元素表達式 |
雖然 Lit 中的大多數 DOM 操作都可以使用模板以宣告方式達成,但進階情況可能需要取得對模板中渲染的元素的參考並以命令式方式操作它。這可能有用的一些常見範例包括將焦點放在表單控制項或在容器元素上呼叫命令式 DOM 操作程式庫。
當放置在模板中的元素上時,ref
指令會在渲染後擷取對該元素的參考。可以透過兩種方式之一擷取元素參考:透過傳遞 Ref
物件或透過傳遞回呼。
Ref
物件充當對元素參考的容器,可以使用 ref
模組中的 createRef
輔助方法建立。渲染後,Ref
的 value
屬性將設定為元素,可以在 updated
等渲染後生命週期中存取它。
@customElement('my-element')
class MyElement extends LitElement {
inputRef: Ref<HTMLInputElement> = createRef();
render() {
// Passing ref directive a Ref object that will hold the element in .value
return html`<input ${ref(this.inputRef)}>`;
}
firstUpdated() {
const input = this.inputRef.value!;
input.focus();
}
}
class MyElement extends LitElement {
inputRef = createRef();
render() {
// Passing ref directive a Ref object that will hold the element in .value
return html`<input ${ref(this.inputRef)}>`;
}
firstUpdated() {
const input = this.inputRef.value!;
input.focus();
}
}
customElements.define('my-element', MyElement);
也可以將 ref 回呼傳遞給 ref
指令。每次參考的元素變更時,都會呼叫回呼。如果在後續渲染中將 ref 回呼渲染到不同的元素位置或移除,它會先使用 undefined
呼叫,然後再使用它渲染到的新元素呼叫(如果有的話)。請注意,在 LitElement
中,回呼將自動呼叫並綁定到主機元素。
@customElement('my-element')
class MyElement extends LitElement {
render() {
// Passing ref directive a change callback
return html`<input ${ref(this.inputChanged)}>`;
}
inputChanged(input?: HTMLInputElement) {
input?.focus();
}
}
class MyElement extends LitElement {
render() {
// Passing ref directive a change callback
return html`<input ${ref(this.inputChanged)}>`;
}
inputChanged(input) {
input?.focus();
}
}
customElements.define('my-element', MyElement);
在遊樂場中進一步探索 ref
。
非同步渲染
連結至「非同步渲染」until
連結至「until」渲染預留位置內容,直到一或多個 Promise 解析為止。
匯入 |
|
簽名 |
|
可用位置 | 任何表達式 |
採用一系列值,包括 Promise。值會依優先順序渲染,第一個引數具有最高優先順序,最後一個引數具有最低優先順序。如果某個值是 Promise,則在它解析之前,會渲染較低優先順序的值。
值的優先順序可用於為非同步資料建立預留位置內容。例如,具有待處理內容的 Promise 可以是第一個(最高優先級)參數,而非 Promise 的載入指示器範本可以用作第二個(較低優先級)參數。載入指示器會立即呈現,而主要內容會在 Promise 解析時呈現。
@customElement('my-element')
class MyElement extends LitElement {
@state()
private content = fetch('./content.txt').then(r => r.text());
render() {
return html`${until(this.content, html`<span>Loading...</span>`)}`;
}
}
class MyElement extends LitElement {
static properties = {
content: {state: true},
};
constructor() {
super();
this.content = fetch('./content.txt').then(r => r.text());
}
render() {
return html`${until(this.content, html`<span>Loading...</span>`)}`;
}
}
customElements.define('my-element', MyElement);
在遊樂場中探索更多關於 until
的用法。
asyncAppend
連結到 “asyncAppend” 的永久連結將 AsyncIterable
中的值在其產生時附加到 DOM 中。
匯入 |
|
簽名 |
|
可用位置 | 子表達式 |
asyncAppend
呈現非同步可迭代物件的值,並在先前的值之後附加每個新值。請注意,非同步產生器也實作了非同步可迭代協定,因此可以被 asyncAppend
取用。
async function *tossCoins(count: number) {
for (let i=0; i<count; i++) {
yield Math.random() > 0.5 ? 'Heads' : 'Tails';
await new Promise((r) => setTimeout(r, 1000));
}
}
@customElement('my-element')
class MyElement extends LitElement {
@state()
private tosses = tossCoins(10);
render() {
return html`
<ul>${asyncAppend(this.tosses, (v: string) => html`<li>${v}</li>`)}</ul>`;
}
}
async function *tossCoins(count) {
for (let i=0; i<count; i++) {
yield Math.random() > 0.5 ? 'Heads' : 'Tails';
await new Promise((r) => setTimeout(r, 1000));
}
}
class MyElement extends LitElement {
static properties = {
tosses: {state: true},
};
constructor() {
super();
this.tosses = tossCoins(10);
}
render() {
return html`
<ul>${asyncAppend(this.tosses, (v) => html`<li>${v}</li>`)}</ul>`;
}
}
customElements.define('my-element', MyElement);
在遊樂場中探索更多關於 asyncAppend
的用法。
asyncReplace
連結到 “asyncReplace” 的永久連結將 AsyncIterable
中產生的最新值渲染到 DOM 中。
匯入 |
|
簽名 |
|
可用位置 | 任何表達式 |
與asyncAppend
類似,asyncReplace
呈現非同步可迭代物件的值,並將先前的值替換為每個新值。
async function *countDown(count: number) {
while (count > 0) {
yield count--;
await new Promise((r) => setTimeout(r, 1000));
}
}
@customElement('my-element')
class MyElement extends LitElement {
@state()
private timer = countDown(10);
render() {
return html`Timer: <span>${asyncReplace(this.timer)}</span>.`;
}
}
async function *countDown(count) {
while (count > 0) {
yield count--;
await new Promise((r) => setTimeout(r, 1000));
}
}
class MyElement extends LitElement {
static properties = {
timer: {state: true},
};
constructor() {
super();
this.timer = countDown(10);
}
render() {
return html`Timer: <span>${asyncReplace(this.timer)}</span>.`;
}
}
customElements.define('my-element', MyElement);
在遊樂場中探索更多關於 asyncReplace
的用法。