stenciljs:插槽问题



我创建了一个简单的web(模具(组件AuthGuard,不要与Angular的AuthGuard混淆。

该组件的目的是检查用户是否已登录。

  • 如果是,则渲染插槽html
  • 如果没有,则渲染"注册"按钮

组件代码如下:

import { Component, Host, h }   from    '@stencil/core';
import { Build, State       }   from    '@stencil/core';
import { AuthService        }   from    'auth/auth.service';
import { ConfigService      }   from    'common/config.service';
@Component({
tag                         :   'auth-guard',
styleUrl                    :   'auth-guard.css',
shadow                      :   true,
})
export class AuthGuard {
@State() canRender          :   boolean             =   false;
componentWillLoad() {
if (Build.isBrowser) {
const timerId       =   setInterval(() => {
if (AuthService.isInitialized) {
AuthService.vol$.subscribe(_u => {
this.canRender= true;
});
clearInterval(timerId);
}
}, ConfigService.loadTime);
}
}
render() {
console.log('auth guard :: render', this.canRender, AuthService.me);
return (
<Host>
{ 
this.canRender ? (
AuthService.me && AuthService.me.id.length > 0 ? (
<slot></slot>
) : (
<ion-button
href="/signup"
routerDirection="forward"
color="danger">
Signup
</ion-button>
)
): null
}
</Host>
);
}
}

现在在另一个文件中,我使用以下代码:

<auth-guard slot='end'>
<volunteer-mini volunteer={AuthService.me}></volunteer-mini>
</auth-guard>

有了这个,我期待的是

  • this.canRender变为true之前,不进行任何渲染
  • 一旦this.canRender变为true,如果AuthService.me有效,则呈现槽HTML
  • 若AuthService.me为null,则呈现注册按钮

但是当this.cannder为false时,它试图将volunteer-mini呈现为槽HTML,这是一个问题。由于volunteer-mini内部依赖于尚未初始化的AuthService.me。

但一旦this.canRender变为真,其他两种情况都可以正常工作。

通常,使用模板编写身份验证保护是个坏主意。核心问题是您的插槽在组件初始化之前就已经存在。

因此,使用您当前的代码,在您决定没有权限后,您必须手动删除插槽。

此外,如果您没有定义插槽位置,但仍在父对象中提供插槽内容,则该内容仍将附加到您的内部子对象。

为了解决这个问题,您可以将组件重构为一个函数,如<Host>,但这还有其他需要考虑的问题。

最新更新