• home > webfront > ECMAS > vue3 >

    vue2升级vue3:Vue Router报错,directly inside <transition> or <keep-a

    Author:zhoulujun Date:

    vue2带缓存的路由重构为 vue3 + tsx,keep-alive 不生效,而且警告

    vue3 报这个错误:

    vue-router.mjs:35 [Vue Router warn]: <router-view> can no longer be used directly inside <transition> or <keep-alive>.

    Use slot props instead:

    <router-view v-slot="{ Component }">

      <keep-alive>

        <component :is="Component" />

      </keep-alive>

    </router-view>

    v-slot这种用法在tsx里应该是不能直接这么使用的,毕竟tsx不比模板,写tsx的本质其实是在写渲染函数,于是去翻阅babel-tsx-plugin的文档

    最终实现代码:

    router

    router 页面设置了keep alive

    const router = [
      {
        path: 'dashboards/:folder_uid/:uid',
        name: 'dashboard-info',
        component: () => import(/* webpackChunkName: "DashboardPreview" */'@/pages/dashboard/dashboard'),
        props: route => ({ uid: route.params.uid }),
        meta: {
          parent: 'dashboard',
        },
      },
      {
        path: 'share-panel/:folder_uid/:uid',
        name: 'sharePanel',
        // component: SharePanel,
        components: {
          keepAlive: () => import(/* webpackChunkName: "SharePanelPage" */ '../pages/dashboard/dashboard-editor'),
        },
        meta: {
          isHideNav: true,
        },
      },
    ]

    当然,也可以使用meta  来控制是否 keep-alive。不然过建议用上面的方式实现。

    App home 页面

    页面路由tsx代码如下:

    import { defineComponent, KeepAlive, Transition, Suspense, computed } from 'vue';
    import { useRoute, RouterView } from 'vue-router';
    import Navigation from '../../components/navigation';
    import Loading from '@/components/loading';
    
    export default defineComponent({
      name: 'HomePage',
      setup() {
        const route = useRoute();
        const isHideNav = computed(() => {
          let { isHideNav } = route.meta;
          if (window.location.search.includes('embed')) {
            isHideNav = true;
          }
          return isHideNav;
        });
        const routeClass = computed(() => {
          if (isHideNav.value) {
            return 'full-page';
          }
          return 'flex-1';
        });
        return () => (
          <div class='full-height flex-column'>
            {!isHideNav.value && (<Navigation/>)}
            <RouterView class={routeClass.value} name='keepAlive'>
              {{
                default: ({ Component, route }: { Component: () => JSX.Element, route: any }) => (
                  <KeepAlive>
                    <Component key={route.meta.usePathKey || route.params.space_uid}/>
                  </KeepAlive>
                ),
              }}
            </RouterView>
            <RouterView class={routeClass.value}>
              {{
                default: ({ Component, route }: { Component: () => JSX.Element, route: any }) => (
                  <Transition name={route.meta.transition || 'fade'} mode='out-in'>
                    <Suspense>
                      {{
                        default: () => <Component key={route.meta.usePathKey || route.params.space_uid}/>,
                        fallback: () => <Loading/>,
                      }}
                    </Suspense>
    
                  </Transition>
                ),
              }}
            </RouterView>
          </div>
        );
      },
    });


    参考链接:

    如何在vue3的jsx中使用keep-alive? https://www.zhihu.com/question/467503706

    https://如何在tsx中使用vue-router4的keep-alive v-direct.xecus.cc/posts/53167.html



    转载本站文章《vue2升级vue3:Vue Router报错,directly inside <transition> or <keep-a》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/ECMAScript/vue3/8862.html

    延伸阅读: