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

[Question] Help 有没有遇到过pro-layout 默认插槽中使用RouterView,而RouterView再使用插槽渲染当前页面对应组件,组件会渲染两次的情况? #251

Open
YTT-TTY opened this issue Oct 28, 2022 · 3 comments
Labels
question Further information is requested

Comments

@YTT-TTY
Copy link

YTT-TTY commented Oct 28, 2022

🧐 问题描述 Problem Description

有没有遇到过pro-layout 默认插槽中使用RouterView,而RouterView再使用插槽渲染当前页面对应组件,组件会渲染两次的情况?

💻 示例代码 Sample code

const BasicLayout = defineComponent({
setup(props, { slots }) {
const multiTabState = useMultiTabStateProvider();
const { layoutConfig, locale, collapsed, selectedKeys, openKeys, menuData, breadcrumb, sideWidth } = useMenuState(multiTabState);

    const breadcrumbRender = ({ route, params, routes }: Breadcrumb) => (
        routes.indexOf(route) === routes.length - 1 ? <span> {route.breadcrumbName}</span>
            : <RouterLink to={{ path: route.path, params }}>{route.breadcrumbName}</RouterLink>
    )

    return () => (
        <ProLayout
            logo={`${process.env.VUE_APP_PUBLIC_PATH}logo.png`}
            locale={locale}
            {...layoutConfig}
            menuData={menuData}
            v-models={[
                [collapsed.value, 'collapsed'],
                [selectedKeys.value, 'selectedKeys'],
                [openKeys.value, 'openKeys'],
            ]}
            breadcrumb={{ routes: breadcrumb.value }}
            v-slots={{
                default: () => <>
                    {SettingConfig.multiTab && <MultiTab fixed={SettingConfig.multiTabFixed} />}

                    <div class={[{ 'ant-layout-content-has-multiTab': SettingConfig.multiTab }]}>
                        <RouterView
                            // TODO优化:会渲染两次
                            v-slots={{
                                default: ({ Component, route }: RouterViewSlot) => (

                                    h(Component)

                                )
                            }}
                        />
                    </div>

                </>,
                breadcrumbRender: ({ route, params, routes }: Breadcrumb) => breadcrumbRender({ route, params, routes }),
                rightContentRender: () => <RightContent />
            }}
        />
    )
}

});

🚑 其他信息 Other information

组件对应代码以及浏览器打印渲染信息

code
页面

@YTT-TTY YTT-TTY added the question Further information is requested label Oct 28, 2022
@lolarun
Copy link
Contributor

lolarun commented Oct 28, 2022

首先,个人建议还是用SFC吧,这TSX写得太碎了....
其次,定位问题建议使用“最小化”原则,即:新建一个“干净”的项目,并引入最少元素。已经说过无数次了,就是不听。

新建项目,使用这个BasicLayout.tsx,即可验证ProLayout的默认插槽中使用RouterView,并不会引发渲染两次的问题。

import { defineComponent, h, type VNode } from 'vue';
import { RouterView } from 'vue-router';
import ProLayout from '@ant-design-vue/pro-layout';

export default defineComponent({
  setup() {
    return () => (
      <ProLayout>
        <RouterView
          v-slots={{
            default: ({ Component }: { Component: VNode }) => h(Component),
          }}
        />
      </ProLayout>
    );
  },
});

最后,多次渲染理的问题大多数是因为状态(响应式数据)发生了变化,建议尝试将多页签相关的代码注释后再试一下,或者直接watch一下SettingConfig

唉,就这?

@YTT-TTY
Copy link
Author

YTT-TTY commented Oct 31, 2022

我创建一个“干净”的项目,并引入了最少元素,还是会打印出来两遍啊

lolarun added a commit to lolarun/codesandbox that referenced this issue Oct 31, 2022
@lolarun
Copy link
Contributor

lolarun commented Oct 31, 2022

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

No branches or pull requests

2 participants