Vue-router重新加载组件

dar*_*i0h 10 vue.js vue-router

我有一些路由,每个路由加载3个组件.所有路线上的两个组件都是相同的.当我在这些路径之间移动时,我想传递新数据,在组件的某个init事件上,我想填充该组件的数据,以便在UI上反映出来.此外,我想重新启动正在加载的组件的引导动画.我该怎么做呢 因为现在,我不知道在组件生命周期中我将获取数据并使用这些新数据重新呈现组件.具体来说,在myapps/1和/ newapp /我有一个主视图组件和一个侧边栏组件.在/ newapp/URL中,我希望侧栏上的所有图标都是红色(主视图上没有任何内容已填充),主视图应为空.在myapps/1上我想将数据从服务器加载到主视图中,如果全部填满,我希望侧边栏上的图标为绿色.现在发生了什么我加载myapps/1,单击侧栏中的第二个项目,主视图更改为第二个视图.然后我router.push("/ newapp /);并且侧边栏停留在第二个项目和第二个主视图.所以router.push("/ myapps /");不重新加载我的侧边栏和我的主视图.

编辑:

在这里,您可以看到我的路线,侧边栏和默认值是相同的.

 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
        }
    }
];
Run Code Online (Sandbox Code Playgroud)

这是我的ProjectMain.vue

<template>
    <div class="wrapper wrapper-content">
        <component :is="currentProjectMain"></component>
    </div>
</template>
Run Code Online (Sandbox Code Playgroud)

这是我在index.html中的路由器视图:

<router-view name="sidebar"></router-view>
Run Code Online (Sandbox Code Playgroud)

我在index.html中有另一个,默认的一个:

<router-view></router-view>
Run Code Online (Sandbox Code Playgroud)

当我单击侧栏上的某个项目时,我向ProjectMain发出事件以切换组件.像这样:在补充工具栏中:

eventBus.$emit("currentProjectMainChanged", "appOverview");
Run Code Online (Sandbox Code Playgroud)

要么

eventBus.$emit("currentProjectMainChanged", "appSettings");
Run Code Online (Sandbox Code Playgroud)

而不是ProjectMain:

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

如果我得到"/ 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">,我想要的是我的bootstrap动画(),我希望Sidebar和ProjectMain完成整个生命周期.我希望在侧边栏上选择默认项(所以appOverview),并在ProjectMain中加载默认组件(所以CurentProjectAppOverview.vue).

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

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

所以像"ReloadComponent:true",或者破坏并重新创建组件.

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

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

Gki*_*kan 15

我面临着同样的问题。我将引用一个找到的答案,这确实很简单而且很棒。最简单的解决方案是在:中添加:key属性

<router-view :key="$route.fullPath"></router-view>
Run Code Online (Sandbox Code Playgroud)

这是因为如果寻址相同的组件,Vue Router不会注意到任何更改。使用该键,对路径的任何更改都将触发使用新数据重新加载组件。

  • 有趣的是,我仍在寻找自己的答案来解决新项目上的这个问题,即使它很简单。这个东西应该在 Vue 的文档中,这是一个必须知道的基本东西。 (3认同)
  • vue router 没有明确的方法来重新加载组件,这有点荒谬。有许多用例,例如当组件依赖于由路由更改设置的存储状态时。beforeChange 中的逻辑混乱就是这样,一团糟,而且根本不可扩展...... (2认同)

dar*_*i0h 8

部分感谢:https : //forum.vuejs.org/t/vue-router-reload-component/4429

我想出了一个适合我的解决方案:

首先,我向jQuery添加了一个新函数,该函数用于在组件加载时重新触发自举动画。

$.fn.redraw = function(){
    return $(this).each(function(){
        var redraw = this.offsetHeight;
    });
};
Run Code Online (Sandbox Code Playgroud)

在组件中:

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");
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

我所说的onCreated();方法将组件载荷,当路线重载或相同路线的变化ID,但该组件保持不变,我只是再次调用该方法。这将处理新数据。

至于重新触发自举动画,我使用的redraw();功能是在应用程序开始时添加到jQuery的。并重新触发URL更改时的动画:

$("#breadcrumbsCurrentProject").find(".animated").removeClass("fadeIn").redraw().addClass("fadeIn");
Run Code Online (Sandbox Code Playgroud)