Subscribe on changes!

resolveComponent支持不抛出警告

avatar
Sep 9th 2022

What problem does this feature solve?

我有个需求:库里的部分组件(其他人不会直接接触到这部分组件,所以不用slot)会有一个默认的占位组件,如果用户注册了他自己的定制组件,就会使用他的定制组件替换掉占位组件。

<script>
export default {
  name: '占位组件示例',
  render() {
    const CustomComp = resolveComponent('custom-comp');
    if(CustomComp === 'custom-comp') {
        return <div>默认的占位</div>;
    }
    return <CustomComp />;
  }
};
</script>

这里,我是有意这么做的,注不注册他自己的定制组件,都不会影响整个应用。 这个找不到组件的警告在我这个场景是不需要存在的。

What does the proposed API look like?

function resolveComponent(name: string, showWarn: boolean): Component | string
avatar
Sep 11th 2022

for me, it think it violate programming intuition.

i think you will use slot in component which user can import it directly.

if user doesn't use slot, innerComp will render. if user use slot, that he can decide component which he want to render in this position.

// InnerComp.vue
export default {
  render() {
      return <div>inner comp</div>;
  }
};
// Comp.vue (user use it directly
export default {
  render() {
      return <div>
          // give choice to user
          {this.$slots.default ? this.$slots.default(): <InnerComp></InnerComp>}
      </div>;
  }
};
avatar
Sep 11th 2022

@Dedicatus546 thanks for your comment. People will not directly use those components which contains default placeholder.

avatar
Sep 11th 2022

i think you could write a ConfigProvider.vue to config some custom component

like naive-ui

image

i think using resolveComponent has significant limitations, such as can't get component context, can't control effect range.

avatar
Sep 11th 2022

@Dedicatus546 that's not a good choice for me.

Bro, u Chinese guy? Chinese directly?

avatar
Sep 11th 2022

@chenhaihong 一般用英语交流

avatar
Sep 12th 2022

@Dedicatus546 兄弟建议你标点符号要加上,还有要加大小写。确实有点难阅读你的句子。

avatar
Sep 12th 2022

The provide/inject API is designed for your use case but resolveComponent isn’t. And like suggested by @Dedicatus546, a ConfigProvider component is also a good choice. Relying on globally registered component with a specific name isn’t a safe design as it makes your component less portable (consider using it inside a project which already has a globally registered custom-comp component).

avatar
Sep 12th 2022

@Justineo 感谢回复。因为我只是阅读了resolveComponent 的使用文档,没了解过它的设计初衷,所以我在我的项目用它来查找一个可能被注册的全局组件是否有存在。

我在写的项目暴露了一个方法用来创建应用,大概像下面这样子,

import { createAdminApp } from 'package-admin'; // 会暴漏类似的方法用来创建管理平台应用

const { app } = createAdminApp({
  // ...  一些定义好的配置,比如路由、侧边栏、导航栏、数据接口
});

app.component('custom-userinfo',  CustomUserinfo); // 如果注册了全局的定制用户信息组件,替换内置的占位组件
app.component('custom-footer', CustomFooter); // 如果注册了全局的定制footer组件,替换内置的占位组件
// ... 其他的可定制组件

这里 provide/injectConfigProvider 并不适合。即使用这两种的其中一种方式,使用起来也会复杂很多。 抛开什么编程范式什么设计初衷,我使用 resolveComponent 来判断全局定制组件是否存在,对于我来说和对于使用者,代码写起来都会简单地很多。

只是因为在开发模式下,浏览器控制台会老是输出警告,所以我来提这个feature。

avatar
Sep 12th 2022

I believe what you need is app.component(name) (without the second argument). But still, I think app.provide fits better to your use case for reasons I mentioned above.