2016-12-23 124 views
1

我有几个路由,每个加载3个组件。两个组件在所有路线上都是相同的。 当我在这些路线之间移动时,我想传递新的数据,并在组件的某个init事件上填充该组件的数据,以便在UI上反映出来。 另外我想要重新加载组件的引导程序动画。 我会如何去做这件事。 因为现在,我不知道组件生命周期中的哪个位置可以获取数据并使用这些新数据重新渲染组件。 Concretly在myapps/1和/ newapp /我有一个主视图组件和一个侧边栏组件。在/ newapp/URL中,我希望侧栏上的所有图标都是红色的(主视图上的任何图标都没有填充),并且主视图应该是空的。 在myapps/1上,我想将服务器中的数据加载到主视图中,如果全部填满,我希望侧栏上的图标变为绿色。 现在发生了什么我加载myapps/1,单击边栏中的第二项,主视图切换到第二个视图。然后我router.push(“/ NEWAPP /)和侧边栏停留在第二项和第二主视图 所以router.push。(” /安装MyApps /“);不重装我的侧边栏和我的主视图Vue路由器重新加载组件

编辑:

这里你可以看到我的路线,侧栏和默认的是相同的

const routes = [ 
    { 
     path: "/myapps/newproject", 
     components: { 
      default: ProjectMain, 
      "breadcrumbs": BreadcrumbsNewProject, 
      "sidebar": SidebarProject 
     } 
    }, 
    { 
     path: "/myapps/:id", 
     components: { 
      default: ProjectMain, 
      "breadcrumbs": BreadcrumbsCurrentProject, 
      "sidebar": SidebarProject 
     } 
    }, 
    { 
     path: "/myapps/newversion/:id", 
     components: { 
      default: ProjectMain, 
      "breadcrumbs": BreadcrumbsNewVersion, 
      "sidebar": SidebarProject 
     } 
    } 
]; 

这是我ProjectMain.vue

<template> 
    <div class="wrapper wrapper-content"> 
     <component :is="currentProjectMain"></component> 
    </div> 
</template> 

这是我的路由器视图索引。 html:

<router-view name="sidebar"></router-view> 

而且,我还有一个index.html中,默认的:

<router-view></router-view> 

当我点击侧边栏上的一些项目我发出事件到ProjectMain转出的组件。所以像这样: 在边栏:

eventBus.$emit("currentProjectMainChanged", "appOverview"); 
在ProjectMain

eventBus.$emit("currentProjectMainChanged", "appSettings"); 

而且比:

eventBus.$on("currentProjectMainChanged", function(data){ 
       if(data === "appOverview"){ 
        self.currentProjectMain = CurrentProjectAppOverview; 
       }else if(data === "appSettings"){ 
        self.currentProjectMain = CurrentProjectSettings; 
       } 
      }); 

如果我到 “/安装MyApps /:ID”。它加载的侧边栏和ProjectMain,我得到了侧边栏的小动画和ProjectMain这个自举类: <div class="animated fadeInUp">和两个组件整个生命周期内得到。

默认appOverview在侧边栏被选择并且CurentProjectAppOverview.vue加载为在ProjectMain的成分。 比我单击边栏中的appSettings和类被添加到边栏中的该项目以标记为选中,并在ProjectMain CurrentProjectSettings.vue作为组件加载。

但在面包屑中,我有一个按钮去“/ myapps/newversion /:id” 这是问题所在。当我点击进入“/安装MyApps/NEWVERSION /:ID”(router.push("/myapps/newversion/" + id);)侧边栏上的第二个项目保持选中状态(的appSettings)和ProjectMain CurrentProjectSettings.vue保持加载,和我没有得到侧边栏的引导动画和ProjectMain,并且组件不会经历它们的生命周期。

当我点击按钮进入“/ myapps/newversion /:id”是我的引导动画(<div class="animated fadeInUp">)时,我想让Sidebar和ProjectMain完成整个生命周期。我希望在侧边栏(如此appOverview)上选择默认项目,并在ProjectMain中加载默认组件(如此CurentProjectAppOverview.vue)。

侧边栏中的每个项目都有彩色按钮。如果我从“/ myapps /:id”去到“/ myapps/newversion /:id”,我想从服务器加载数据到CurrentProjectAppOverview.vue,如果所有数据都被填充了,我希望侧边栏上的按钮是绿色,如果不是,它应该是红色的。

所以简而言之,当在这两条路线之间移动时,我希望能够加载数据并填充我想要的字段,并且我想要选择并加载引导动画和默认视图,并且它们应该贯穿整个生命周期。现在路由器只是重用它们。

所以像“ReloadComponent:true”,或摧毁并重新创建组件。

我可以复制SidebarProject.vue和ProjectMain.vue并重命名它们,并在每个路由加载基本上一个副本,但这意味着我必须在不同的.vue文件中编写相同的代码。

之前有一个选项将YouComponent.route.canReuse设置为false,这将做我想做的,但我认为,但它在最新版本中被删除。

+0

请添加代码。 – retrograde

+0

我添加了代码和更多解释。 –

回答

1

部分感谢名单这样的:https://forum.vuejs.org/t/vue-router-reload-component/4429

我拿出这对我工作的解决方案:

首先,我添加了一个新功能的jQuery这是用来重新触发引导动画时,该组件加载。

$.fn.redraw = function(){ 
    return $(this).each(function(){ 
     var redraw = this.offsetHeight; 
    }); 
}; 

在组件:

export default{ 
     created:function(){ 
      this.onCreated(); 
     }, 
     watch: { 
      '$route' (to, from) { 
       //on route change re run: onCreated 
       this.onCreated(); 

       //and trigger animations again 
       $("#breadcrumbsCurrentProject").find(".animated").removeClass("fadeIn").redraw().addClass("fadeIn"); 
      } 
     } 
} 

我称之为onCreated();方法将组件载荷,当线路重载或相同路由变化的ID,但该组件保持不变,只需要调用方法再次。这照顾了新的数据。

至于重新引导引导动画,我使用redraw();函数,我将jQuery添加到应用程序的开头。这再次引发对URL变化的动画:

$("#breadcrumbsCurrentProject").find(".animated").removeClass("fadeIn").redraw().addClass("fadeIn"); 
+0

你可以做的另一件事是使用你的组件内置的beforeRouteEnter函数来拦截路由改变 –

2

看起来你正在使用vue-router。

我没有你的代码,但我可以告诉你我是如何处理这个的。 See named-views

这里是我的bundle.js文件我的路由器地图:

const router = new VueRouter({ 
routes: [ 
    { path: '/', 
     components: { 
     default: dashboard, 
     altside: altSide, 
     toolbar: toolbar 
     }, 
    }, 
    { path: '/create', 
     components: { 
     default: create, 
     altside: altSide, 
     toolbar: toolbar 
     }, 
    }, 
    { path: '/event/:eventId', 
     name: 'eventDashboard', 
     components: { 
      default: eventDashboard, 
      altside: altSide, 
      toolbar: eventToolbar, 
     }, 
     children: [ 
      { path: '/', name: 'event', component: event }, 
      { path: 'tickets', name: 'tickets', component: tickets}, 
      { path: 'edit', name: 'edit', component: edit }, 
      { path: 'attendees', name: 'attendees', component: attendees}, 
      { path: 'orders', name: 'orders', component: orders}, 
      { path: 'uploadImage', name: 'upload', component: upload}, 
      { path: 'orderDetail', name: 'orderDetail', component: orderDetail}, 
      { path: 'checkin', name: 'checkin', component: checkin}, 
     ], 
    } 
] 
}) 

我已经命名的意见“默认”,“altside”和“工具栏”我分配给命名视图组件为每条路径。

的这个第二部分是在你的父组件,你指定的名称

<router-view name="toolbar"></router-View> 

这里是我的父模板:

<template> 

    <router-view class="view altside" name="altside"></router-view> 
    <router-view class="view toolbar" name="toolbar"></router-view> 
    <router-view class="view default"></router-view> 
</template> 

所以,我所做的是我告诉父模板查看路由器视图的named-view。并根据路径,拉出我在路由器映射中指定的组件。

对于我的'/'路径工具栏==工具栏组件,但在'/ create'路径toolbar = eventToolbar组件。

默认组件是动态的,它允许我使用子组件,而不用交换工具栏或altside组件。

+0

请看看我的更新 –

0

这是我想出了:

import ProjectMain from './templates/ProjectMain.vue'; 
import SidebarProject from './templates/SidebarProject.vue'; 

//现在浅拷贝的对象,因此新对象作为seperatete .vue文件处理有:$.extend({}, OriginalObject); //这是所以我不必须创造基本相同。因为它们是不同的VUE文件,但VUE路由器将重新载入这些文件

const ProjectMainA = $.extend({}, ProjectMain); 
const ProjectMainB = $.extend({}, ProjectMain); 
const ProjectMainC = $.extend({}, ProjectMain); 
const SidebarProjectA = $.extend({}, SidebarProject); 
const SidebarProjectB = $.extend({}, SidebarProject); 
const SidebarProjectC = $.extend({}, SidebarProject); 

const routes = [ 
{ 
path: "/myapps/newproject", 
components: { 
default: ProjectMainA, 
"breadcrumbs": BreadcrumbsNewProject, 
"sidebar": SidebarProjectA 
} 
}, 
{ 
path: "/myapps/:id", 
components: { 
default: ProjectMainB, 
"breadcrumbs": BreadcrumbsCurrentProject, 
"sidebar": SidebarProjectB 
} 
}, 
{ 
path: "/myapps/newversion/:id", 
components: { 
default: ProjectMainC, 
"breadcrumbs": BreadcrumbsNewVersion, 
"sidebar": SidebarProjectC 
} 
} 
]; 

这基本上招数VUE路由器,以为他是加载不同.vue成分,但它们实际上是相同的。所以我得到了我想要的一切:重新加载组件,动画,生命周期,而且我不必编写多个相似或相同的组件。 您怎么看,我只是不确定这是否是最佳做法。

相关问题