LitElement manages your declared properties and their corresponding attributes. By default, LitElement will:
Ensure that an element update is scheduled when any declared property changes.
Capture instance values for declared properties. Apply any property values that are set before the browser registers a custom element definition.
Set up an observed (not reflected) attribute with the lowercased name of each property.
Handle attribute conversion for properties declared as type String, Number, Boolean, Array, and Object.
Use direct comparison (oldValue !== newValue) to test for property changes.
Apply any property options and accessors declared by a superclass.
Remember to declare all of the properties that you want LitElement to manage. For the property features above to be applied, you must declare the property.
The options object can have the following properties:
attribute
Whether the property is associated with an attribute, or a custom name for the associated attribute. Default: true. See Configure observed attributes. If attribute is false, the converter, reflect and type options are ignored.
A function that takes an oldValue and newValue and returns a boolean to indicate whether a property has changed when being set. If unspecified, LitElement uses a strict inequality check (newValue !== oldValue) to determine whether the property value has changed.
noAccessor
Set to true to avoid generating the default property accessor. Default: false.
reflect
Whether property value is reflected back to the associated attribute. Default: false. See Configure reflected attributes.
type
A type hint for converting between properties and attributes. This hint is used by LitElement's default attribute converter, and is ignored if converter is set. If type is unspecified, behaves like type: String. See Use LitElement's default attribute converter.
An empty options object is equivalent to specifying the default value for all options.
An options object by another name. This guide uses the descriptive term "options object." In practice the options object is an instance of PropertyDeclaration, so you'll see that name if you're using an IDE, or looking at the API reference. By either name, it's an object that defines a set of options.
Use the @property decorator to declare properties (instead of the static properties field).
@property({type: String})
mode='auto';
@property()
data= {};
The argument to the @property decorator is an options object. Omitting the argument is equivalent to specifying the default value for all options.
Using decorators. Decorators are a proposed JavaScript feature, so you'll need to use a transpiler like Babel or the TypeScript compiler to use decorators. See Using decorators for details.
There is also an @internalProperty decorator for private or protected properties that should trigger an update cycle. Properties declared with @internalProperty shouldn't be referenced from outside the component.
@internalProperty()
protectedactive=false;
The @internalProperty decorator automatically sets attribute to false; the only option you can specify for an internal property is the hasChanged function.
The @internalProperty decorator can serve as a hint to a code minifier that the property name can be changed during minification.
A property change can trigger an asynchronous update cycle, which causes the component to re-render its template.
When a property changes, the following sequence occurs:
The property's setter is called.
The setter calls the property's hasChanged function. The hasChanged function takes the property's old and new values, and returns true if the change should trigger an update. (The default hasChanged uses a strict inequality test (oldValue !== newValue) to determine if the property has changed.)
If hasChanged returns true, the setter calls requestUpdate to schedule an update. The update itself happens asynchronously, so if several properties are updated at once, they only trigger a single update.
The component's update method is called, reflecting changed properties to attributes and re-rendering the component's templates.
There are many ways to hook into and modify the update lifecycle. For more information, see Lifecycle.
Typically, you initialize property values in the element constructor.
When using decorators, you can initialize the property value as part of the declaration (equivalent to setting the value in the constructor).
You may want to defer initializing a property if the value is expensive to compute and is not required for the initial render of your component. This is a fairly rare case.
Initialize property values in the element constructor
While element properties can be of any type, attributes are always strings. This impacts the observed attributes and reflected attributes of non-string properties:
To observe an attribute (set a property from an attribute), the attribute value must be converted from a string to match the property type.
To reflect an attribute (set an attribute from a property), the property value must be converted to a string.
An observed attribute fires the custom elements API callback attributeChangedCallback whenever it changes. By default, whenever an attribute fires this callback, LitElement sets the property value from the attribute using the property's fromAttribute function. See Convert between properties and attributes for more information.
By default, LitElement creates a corresponding observed attribute for all declared properties. The name of the observed attribute is the property name, lowercased:
// observed attribute name is "myprop"
myProp: { type: Number }
To create an observed attribute with a different name, set attribute to a string:
// Observed attribute will be called my-prop
myProp: { attribute: 'my-prop' }
To prevent an observed attribute from being created for a property, set attribute to false. The property will not be initialized from attributes in markup, and attribute changes won't affect it.
You can configure a property so that whenever it changes, its value is reflected to its observed attribute. For example:
// Value of property "myProp" will reflect to attribute "myprop"
myProp: {reflect: true}
When the property changes, LitElement uses the toAttribute function in the property's converter to set the attribute value from the new property value.
If toAttribute returns null, the attribute is removed.
If toAttribute returns undefined, the attribute is not changed.
If toAttribute itself is undefined, the attribute value is set to the property value without conversion.
LitElement tracks reflection state during updates. LitElement keeps track of state information to avoid creating an infinite loop of changes between a property and an observed, reflected attribute.
// retrieve the old property value and store the new one
this.requestUpdate('myProp', oldValue);
}
getmyProp() { ... }
...
// Later, set the property
this.myProp='hi'; // Invokes your setter
If your class defines its own accessors for a property, LitElement will not overwrite them with generated accessors. If your class does not define accessors for a property, LitElement will generate them, even if a superclass has defined the property or accessors.
The setters that LitElement generates automatically call requestUpdate. If you write your own setter you must call requestUpdate manually, supplying the property name and its old value.
Example
A common pattern for accessors is to store the property value using a private property that's only accessed inside the component. This example uses an underscore prefix (_prop) to identify the private property—you could also use TypeScript's private or protected keywords.
In rare cases, a subclass may need to change or add property options for a property that exists on its superclass.
To prevent LitElement from generating a property accessor that overwrites the superclass's defined accessor, set noAccessor to true in the property declaration:
All declared properties have a function, hasChanged, which is called when the property is set.
hasChanged compares the property's old and new values, and evaluates whether or not the property has changed. If hasChanged returns true, LitElement starts an element update if one is not already scheduled. See the Element update lifecycle documentation for more information on how updates work.
By default:
hasChanged returns true if newVal !== oldVal.
hasChanged returns false if both the new and old values are NaN.
To customize hasChanged for a property, specify it as a property option:
myProp: { hasChanged(newVal, oldVal) {
// compare newVal and oldVal
// return `true` if an update should proceed
}}
hasChanged may not be called for every change. If a property's hasChanged returns true once, it won't be called again until after the next update, even if the property is changed multiple times. If you want to be notified each time a property is set, you should create a custom setter for the property, as described in Create your own property accessors.
Example: Configure property changes
import { LitElement, html } from'lit-element';
classMyElementextendsLitElement {
staticgetproperties(){ return {
myProp: {
type: Number,
/**
* Compare myProp's new value with its old value.
*
* Only consider myProp to have changed if newVal is larger than