lit introduces an example of "Change detection" at the following URL. https://lit.dev/playground/#sample=examples/properties-has-changed
Why is there a "." at the beginning of "date" when specifying the "date-display" option in line 16 of my-element.ts?
import { LitElement, html} from "lit";
import {customElement, property} from 'lit/decorators.js';
import {localDateFromUTC} from './date-utils.js';
import './date-display.js';
@customElement('my-element')
class MyElement extends LitElement {
@property() date?: Date;
render() {
return html`
<p>Choose a date:
<input type="date" @change=${this._dateChanged}></p>
<p><button @click=${this._chooseToday}>Choose Today</button></p>
<p>Date chosen: <date-display .date=${this.date}></date-display></p>
`;
}
_dateChanged(e: Event) {
const utcDate = (e.target as HTMLInputElement).valueAsDate;
if (utcDate) {
this.date = localDateFromUTC(utcDate);
}
}
_chooseToday() {
this.date = new Date();
}
}
Lit uses prefixes to indicate the type of expression in a component's template. The .
prefix denotes a property expression; without the prefix it would be an attribute expression. Using a property expression makes it very easy and convenient to pass any JS object to a child element (in this case a Date
object).
When using HTML attributes you need to be aware that they are always strings. JS data must be converted to a string on the parent element, and then possibly converted back to the corresponding JS type on the child element. No such conversion is performed with property expressions, because the data stays in "JS land".
So, why not always use property expressions? Two examples come to my mind right away:
For a property expression to work you need to know an implementation detail of the child element, i.e. that it has a corresponding JS property. (If you're dealing with your own Lit based elements inside a single project that is not a problem.)
If you want to apply selectors based on attributes (e.g. for styling my-button[disabled] { /* CSS ... /* }
or using querySelector).