繁体   English   中英

Vue - 在动态加载的组件上将组件传递给路由器视图

[英]Vue - Pass components to router-view on dynamically loaded component

我需要为具有不同组件的特定 URI 为同一路由呈现不同的布局,具体取决于用户在移动设备上还是桌面上。

我想避免在 PageCommon(布局组件)中进行路由路径检查以保持其清洁。

该应用程序有一个负责布局的主要组件,它具有不同的路由器视图,我们在其中为每个页面 URI 加载不同的组件。 这将是一条正常的路线。

{
    path: '',
    component: PageCommon,
    children: [
      {
        path: '',
        name: 'Home',
        components: {
          default: Home,
          header: Header,
          'main-menu': MainMenu,
          'page-content': PageContent,
          footer: Footer,
          'content-footer': ContentFooter
        }
      },

加载组件后,我无法更改路由组件属性,因此我尝试制作包装器并动态传递组件。

 {
    path: 'my-view',
    name: 'My_View',
    component: () => import('@/components/MyView/ViewWrapper')
  },

在 /components/MyView/ViewWrapper'

    <page-common v-if="isMobile">
        <my-mobile-view is="default"></my-mobile-view>
        <main-menu is="main-menu"></main-menu>     
    </page-common>    
    <page-common v-else>
        <my-desktop-view is="default"></my-desktop-view>
        <header is="header"></header>    
        <main-menu is="main-menu"></main-menu>    
        <footer is="footer"></footer> 
    </page-common>    

</template>

我希望在 page-common 块中传递的组件将被适当地替换,但这不是它的工作方式,并且 Vue 只是加载带有空路由器视图的 page-common 组件。

有什么办法吗?

请注意,我已经尝试使用:is 属性来加载不同的组件,但问题在于如何告诉父级在此页面上使用这个或那个组件。 这是代码:

<template>
    <component :is="myView"></component>    
</template>
<script>
import DesktopView from "@/components/MyView/DesktopView";
import MobileView from "@/components/MyView/MobileView";
export default {
    name: 'MyView', 
    components: {
        DesktopView,
        MobileView,
    },
    data(){
        return {
            myView: null,
            isMobile: this.detectMobile()
        }
    },
    methods : {
        getViewComponent() {
            return this.isMobile ? 'mobile-view' : 'desktop-view';
        }
    },
    created() {
        this.myView = this.getViewComponent();
    }
}
</script>

我可以对每个PageCommon路由器视图使用这种方法,为每个执行上述操作的组件创建一个组件,但它看起来是一个非常糟糕的解决方案。

您只需要一个计算方法。

您应该在App.vue中有这个顶级逻辑,并且<router-view>应该放在DesktopViewMobileView中。

// App.vue

<template>

    <component :is="myView"></component>   
 
</template>

<script>

import DesktopView from "@/components/MyView/DesktopView";
import MobileView from "@/components/MyView/MobileView";

export default {

    name: 'MyView', 

    components: {
        DesktopView,
        MobileView,
    },

    computed: {
     
      myView() {

        return this.detectMobile() ? 'mobile-view' : 'desktop-view';

      }

   }

}
</script>

您可能还需要考虑通过为这些布局设置动态组件来进行代码拆分,因为 Mobile 将加载桌面视图,因为它已编译到最终构建中,将它们全局注册为动态导入,而不是在MyView中导入它们,然后在完成后删除components相反,这样只会下载需要的那个,从而节省移动用户的带宽:

// main.js

import LoadingDesktopComponent from '@/components/LoadingDesktopComponent '

Vue.componenet('desktop-view', () => ({
  component: import('@/components/MyView/DesktopView'),
  loading: LoadingDesktopComponent // Displayed while loading the Desktop View
})

// LoadingDesktopComponent .vue

<template>

  <div>
    Optimizing for Desktop, Please wait.
  </div>

</template>

<script>

export default {

  name: 'loading-component'

}

</script>

只有当<router-view>可用时才会处理路由逻辑,这意味着您可以延迟 Vue Router 的呈现,例如,您可以在显示组件之前在任何 URI :is显示一个像加载屏幕一样的启动屏幕:is包含<router-view> ,只有到那时才会处理 URI 以显示相关内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM