Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PageJS and WebComponents #569

Open
aress31 opened this issue Aug 8, 2020 · 3 comments
Open

PageJS and WebComponents #569

aress31 opened this issue Aug 8, 2020 · 3 comments

Comments

@aress31
Copy link

aress31 commented Aug 8, 2020

Hi everyone,

I am considering moving from Vaadin Router to PagesJS since PagesJS is almost half the size. I am creating a project using web components - https://github.com/open-wc/open-wc - I need to have a centralized place where I configure the router (ideally using a JSON object of all my routes) and make it accessible application wide.

What would be the best way to proceed?

Thanks in advance,
Alex

@jorenbroekema
Copy link

jorenbroekema commented Aug 9, 2020

I use it in a web component based app so I'll just share a snippet.

class MyApp extends HTMLElement {
  constructor() {
    super();
    this.currentPage = 'home';
  }

  connectedCallback(c) {
    this.setupRouting();
  }

  setupRouting() {
    page('*', (ctx, next) => {
      // do stuff on each page request
      next();
    });

    page('/', () => {
      this.currentPage = 'home';
      this.pageTemplate = html`
        <jb-home></jb-home>
      `;
    });
  
    page('/work', () => {
      this.currentPage = 'work';
      this.pageTemplate = html`
        <jb-work></jb-work>
      `;
    });
  
    page();

    this.addEventListener('change-route', e => {
      page(`/${e.detail}`);
    });
  }

  render() {
    this.innerHTML = `
      <jb-nav></jb-nav>
      ${this.pageTemplate}
    `;
  }
}

This app shell is the top most component in my app, you just re-render whenever currentChange property changes. Simplest way is to create getter/setter for it, reflect to an attribute, and listen for attributeChangedCallback, and call the render method when the value of the attribute is different than current. That, or add a MutationObserver or something.
Libraries like LitElement, stencil, Fast element, etc. etc. all provide you with easy helpers for changing props + re-rendering what has changed.

Some component deep deep down that has a click that changes the route

<jb-button
  @click=${() =>
    host.dispatchEvent(
      new CustomEvent('change-route', { bubbles: true, composed: true, detail: 'work' }),
    )}
  >EXPLORE WORK</jb-button
>

This event gets caught in the app shell on the event listener for change-route, if you set composed:true it also goes through shadow dom boundaries. The "normal" way would just be through anchors with href attributes though, usually.

@klauss194
Copy link

Did anyone else try this with webcomponents ? ( Lit in particular )

@jorenbroekema
Copy link

Lit works with it as well, very similar to my snippet using HTMLElement, except you use LitElement

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants