带有 vaadin 路由器和处理页面刷新的 vanilla js web 组件中的嵌套路由

时间:2021-03-06 03:39:01

标签: javascript html vaadin router web-component

我有一个简单应用程序的嵌套页面布局。 app-layout

我正在尝试将嵌套的子组件加载到它们的特定目标插座中。

vaadin 路由器仅提供一种插座配置。这意味着我的所有路线都将呈现在一个 div 中。

稍微调整一下,我就可以动态设置路由渲染目标,并且可以正常工作,但是在重新加载页面时会失败。

这是我的 vaadin 调整动作功能

// a custom function to set/change the render target at runtime

const setViewPort = async (context, commands) => {
    console.log(window.performance.getEntriesByType("navigation")[0].entryType);
    if(context?.route?.parent?.component){
        let elm = await document.querySelector(context.route.parent.component);
            let outlet = await elm.shadowRoot.querySelector(context.route.viewport);
            await context.resolver.setOutlet(outlet);
    } else {
        let outlet = await document.querySelector(context.route.viewport);
        await context.resolver.setOutlet(outlet);
    }
    return true;
}

这是路由器配置

import {Router} from 'https://unpkg.com/@vaadin/router';

const outlet = document.getElementById('outlet'); //default outlet
const router = new Router(outlet);
router.setRoutes([
    {
        path: '/',
        name: 'home',
        viewport: 'div#outlet',  // extra custom attributes added for runtime check 
        action: setViewPort,    
        component: 'home-view'
    },
    {
        path: '/list',
        name: 'itemsList',
        component: 'item-list',
        renderTarget: 'some-div',
        children:[
            {
                path: '/',
                name: 'itemHome',
                viewport: 'div#outlet',
                action: setViewPort,
                component: 'item-list'
            },
            {
                path: 'inbox',
                name: 'email-inbox',
                viewport: 'div#outlet',
                action: setViewPort,
                component: 'in-box'
            },
            {
                path: 'sent',
                name: 'sent-emails',
                viewport: 'div#outlet',
                action: setViewPort,
                component: 'sent-mails'
            },
            {
                path: 'trash',
                name: 'trash',
                viewport: 'div#outlet',
                action: setViewPort,
                component: 'trash-bin'
            }
        ]
    }
]);

所有这些组件都是带有 shadow dom 的简单 vanilla js web 组件。

此 hack 有效并将单击的项目呈现到其目标 div 中,但在页面重新加载时,根级路由工作正常,但是嵌套路由会引发此错误

Uncaught (in promise) TypeError: Cannot read property 'shadowRoot' of null
at Object.setViewPort [as action]

知道如何修复它吗?改善了吗?还是处理嵌套渲染的更好方法?

0 个答案:

没有答案