昨天我們初步使用 vite
+ TypeScript
+ Lit
建立了初步的元件架構。
那麼今天,我們就接續來說說 Lit 的其他方法及功能吧!
@property
在最初學習 Web Component 時,我們花了兩篇章來詳細說明了 attribute
及 property
的用法。
<custom-input label="text"></custom-input>
並且要透過 observedAttributes
以及 attributeChangedCallback
來監聽屬性變化,在實作表單元件的那幾篇文章中,我想你應該覺得 attributeChangedCallback 變得很長,難以閱讀以及維護。
get label() {
return this._label;
}
set label(value) {
this._label = value;
}
而 Lit 透過 static properties
或 @property()
,讓彼此可以自動同步,不用再手動寫一堆的程式碼。
屬性 | 說明 | 非必填 / 預設值 |
---|---|---|
type |
將 Attribute 字串解析為指定的類型傳給 Property | 非必填,預設為 string |
attribute |
Property 是否與某個 Attribute 關聯 | 非必填,預設為 true |
reflect |
是否同步到 Attribute | 非必填,預設為 false |
hasChanged |
用來確定屬性值是否變更的方法 | 非必填,預設使用 (newValue !== oldValue) |
converter |
用於在屬性和 Attribute 之間轉換的自訂轉換器 | 非必填,未指定時使用預設屬性轉換器 |
noAccessor |
設定為 true 以避免產生預設屬性存取器 |
非必填,預設為 false |
其他更詳細的用法及說明請詳見 Lit。
@property
。tsconfig.json
加入:# 保持舊行為,不會破壞 Lit 的 getter/setter 反應性
"useDefineForClassFields": false,
如果沒加入的話,將會得到錯誤:
使用 @property
加入屬性:
import { property } from 'lit/decorators.js';
@property({ type: String, reflect: true }) name!: string;
@property({ type: Number }) age!: number;
constructor() {
super();
this.name = 'Ada';
this.age = 18;
}
@property({ type: String, reflect: true }) name = 'Ada';
@property({ type: Number }) age = 18;
static properties
。static properties = {
name: { type: String, reflect: true },
age: { type: Number }
};
constructor() {
super();
this.name = 'Ada';
this.age = 18;
}
假設今天這個 counter 需要紀錄 count
、disabled
以及 title
,並且都要同步到 attribute。
@customElement('counter-btn')
export class CounterBtn extends LitElement {
@property({ type: Number, reflect: true }) count!: number;
@property({ type: Boolean, reflect: true, }) disabled!: boolean;
@property({ type: String, reflect: true, }) title!: string;
constructor() {
super();
this.count = 10;
this.disabled = false;
this.title = 'WC-Lit Counter'
}
static styles = css`
// ...以下略
`
以上你已經成功的設定好 property 了,但是我們應該怎麼應用到模板上呢?
這時,我們就需要來介紹一些 Lit 的模板表達式 expressions
。
我們先介紹兩種模板表達式:基本插值 Child nodes & Attributes
, 布林屬性 Boolean Attributes
。
Child nodes & Attributes
${}
來做字串或變數插值,直接將值放入模板中,像範例中的 ${activeClass}
, ${name}
都可以視為一般的變數值插入。<button class=${activeClass}>Button: ${name}</button>
Boolean Attributes
?
的前綴於屬性名稱前。?disabled
表達式的結果是 true,則新增 disabled 屬性;如果計算結果是 false,則刪除 disabled 屬性。<!-- 如果 noValue 為真,則加入 disabled,反之則移除 -->
<button ?disabled=${!noValue}>Click me!</button>
接下來,就將上方定義的 property 加入模板中吧!
render() {
return html`
<div class="counter-wrapper">
<h3>${this.title}</h3>
<div class="counter">
<button class="decrement">-</button>
<span>Count: ${this.count}</span>
<button class="increment">+</button>
</div>
<button class="reset" ?disabled=${this.disabled}>
Reset
</button>
</div>
`;
}
可以發現,我們定義的 title 以及初始 count 的值是從 10 開始,畫面上也有出現了!
接下來,先手動將 disabled 改為 true,並為按鈕加上 disabled 的 class,可以看見畫面也改變了。
到這裡,就將 Lit 框架的初步屬性方法與概念都介紹完了。
目前的元件都還是處於靜態的畫面,下一篇,一樣要讓元件可以動起來
(ㄏ ̄▽ ̄)ㄏ ㄟ( ̄▽ ̄ㄟ)!
程式碼請詳見 Github。