-
Notifications
You must be signed in to change notification settings - Fork 1
Props vs Attributes
Julian Müller edited this page Feb 10, 2023
·
5 revisions
I found this a bit confusing, so I experimented a bit. Here's the lessons learnt:
Using lit and typescript, I declared a property in three different ways:
- As an attribute
@property({attribute: 'litprop-attr'})
litPropAttr: string = 'default'
- As a property that is not an attribute
@property({attribute: false})
litPropNoAttr: string = 'default'
- As a regular class member
noLitPropNoAttr: string = 'default'
Then I loaded the WebComponent into a Vue Component and tried to bind a value to those variables like so:
:litprop-attr="debugVar"
:lit-prop-no-attr="debugVar"
:no-lit-prop-no-attr="debugVar"
And using the prop
modifier:
:litprop-attr.prop="debugVar"
:lit-prop-no-attr.prop="debugVar"
:no-lit-prop-no-attr.prop="debugVar"
I first tested whether the binding worked, so if the default
value in the WebComponent gets replaced when first rendering it.
Then I tried to trigger updates in the values by changing the value of debugVar
in the Vue Component.
Lastly, I tried to set the values explicitly using document.getElementById
.
Here's the results of these experiments:
Declaration Type | Prop Modifier Used | Updating by... | Initial Binding Works | Updating Works |
requestUpdate and updated triggered |
---|---|---|---|---|---|
Attribute | - | changing debugVar
|
Yes | Yes | Yes |
Property | - | changing debugVar
|
No | No | No |
Member | - | changing debugVar
|
No | No | No |
Attribute | + | changing debugVar
|
No | No | No |
Property | + | changing debugVar
|
Yes | Yes | Yes |
Member | + | changing debugVar
|
Yes | Yes | No |
Attribute | - | direct access | Yes | Yes | Yes |
Property | - | direct access | No | Yes | Yes |
Member | - | direct access | No | Yes | No |
Attribute | + | direct access | No | Yes | Yes |
Property | + | direct access | Yes | Yes | Yes |
Member | + | direct access | Yes | Yes | No |
Takeaway:
- As expected, using a class member as a property is not a good idea because even though it is reactive when bound with
.prop
, thelit
hooks are never invoked. - Declaring as attribute and not using
.prop
behaves identical to declaring as property and using.prop
, at least in these experiments. The only difference I could observe so far is if I don't use.prop
, the variables show up in the HTML tree:
Whereas if I do use.prop
, they are not there:
I am not sure what implications this has, will update this page if I find out ;-) For now I will just always use.prop
and setattribute: false
.