![](/img/trans.png)
[英]Vue 3: How to pass data from component to App.vue when there is a router-view in between?
[英]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>
应该放在DesktopView
和MobileView
中。
// 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.