I'm having fun using lit-html with vanillajs, after I saw a tweet from Marc Grabanski suggesting he didn't use the full Lit library. Admittedly I am then not taking advantage of all the reactivity goodness, but I also really dislike the decorators syntax and 95% of the time I just don't need the reactivity after the first render.
It works great! I was amazed at how you can do so much in templates, it's pretty much everything I could do in Vue templates, though a little more verbose.
I built my own `VanillaComponent` class, which has a mount() method which calls the render() function which I define on the child class.
let myComponent = new MyComponent({ label: "I am a button" });
let target = document.querySelector("#demo");
myComponent.mount(target);
The base class stores the root node (target), so later I can do
myComponent.update()
to re-render, taking advantage of lit-html's "diffing" logic.
However something I have not been able to solve with lit-html only, is when I compose parent and child components I have to do something like :
class MyDialog extends VanillaComponent {
render() {
let childComponent ... // another VanillaComponent previously instanced
return html`
<div>
${childComponent.render()}
</div>
So the child component I need to explicitly call render() to get the TemplateResult for the parent template.
But this means I can not do `childComponent.update()` because I don't know the root element of child component, since I did not mount it explicitly myself.
I mean technically because of the lit-html optimizations, I can do `.update()` on myDialog (the parent component) after any child component's props changes, and it will only re-render what is necessary... but let's say my child component has like 1000 cards... it seems very wasteful and it would be ideal if I could re-render only the child.
I wonder if there is a trick to get around that with just lit-html?
It's always worth checking the lit built in directives list for the one you've still missed (or at least it is for me ;).
I think in this case the ref() directive - i.e. https://lit.dev/docs/templates/directives/#ref - may be what you want. If it isn't exactly, reading how it's implemented would be my first step towards building something similar that is.
Thanks I created a custom directive, it's just ten lines of code and it works beautifully. Simply grabbed the `part.parentNode` property. I did the same for a `transition` directive that does something similar to using `appear` in Vue transition to have a nice fade in on first load.
It works great! I was amazed at how you can do so much in templates, it's pretty much everything I could do in Vue templates, though a little more verbose.
I built my own `VanillaComponent` class, which has a mount() method which calls the render() function which I define on the child class.
My VanillaComponent class looks like this:
So I can write something like Then I can instance like so: The base class stores the root node (target), so later I can do to re-render, taking advantage of lit-html's "diffing" logic.However something I have not been able to solve with lit-html only, is when I compose parent and child components I have to do something like :
So the child component I need to explicitly call render() to get the TemplateResult for the parent template.But this means I can not do `childComponent.update()` because I don't know the root element of child component, since I did not mount it explicitly myself.
I mean technically because of the lit-html optimizations, I can do `.update()` on myDialog (the parent component) after any child component's props changes, and it will only re-render what is necessary... but let's say my child component has like 1000 cards... it seems very wasteful and it would be ideal if I could re-render only the child.
I wonder if there is a trick to get around that with just lit-html?