それぞれ3つのコンポーネントをロードするいくつかのルートがあります。 2つのコンポーネントはすべてのルートで同じです。これらのルート間を移動するとき、新しいデータを渡し、コンポーネントの一部の初期化イベントで、そのコンポーネントのデータを入力して、UIに反映するようにします。また、ロードされているコンポーネントのbootstrapアニメーションをリトリガーします。それをどうやってやろうか。現時点では、コンポーネントのライフサイクルのどこでデータを取得し、この新しいデータでコンポーネントを再レンダリングするのかわからないからです。具体的にmyapps/1と/ newapp /には、メインビューコンポーネントとサイドバーコンポーネントがあります。/newapp/URLで、サイドバーのすべてのアイコンを赤にし(メインビューには何も表示されていません)、メインビューを空にする必要があります。 myapps/1で、サーバーからメインビューにデータをロードし、すべてが埋まっている場合は、サイドバーのアイコンを緑色にする必要があります。今、myapps/1をロードし、サイドバーの2番目のアイテムをクリックすると、メインビューが2番目のビューに変わります。その後、router.Push( "/ newapp /);とサイドバーは2番目のアイテムと2番目のメインビューに留まります。したがって、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
}
}
];
_
これは私のProjectMain.vueです
_<template>
<div class="wrapper wrapper-content">
<component :is="currentProjectMain"></component>
</div>
</template>
_
これはindex.htmlの私のルータービューです:
_<router-view name="sidebar"></router-view>
_
そして、index.htmlにもう1つ、デフォルトのものがあります。
_<router-view></router-view>
_
サイドバーの項目をクリックすると、ProjectMainにイベントを発行してコンポーネントを切り替えます。このように:サイドバーで:
_eventBus.$emit("currentProjectMainChanged", "appOverview");
_
または
_eventBus.$emit("currentProjectMainChanged", "appSettings");
_
そしてProjectMainより:
_eventBus.$on("currentProjectMainChanged", function(data){
if(data === "appOverview"){
self.currentProjectMain = CurrentProjectAppOverview;
}else if(data === "appSettings"){
self.currentProjectMain = CurrentProjectSettings;
}
});
_
「/ myapps /:id」に到達した場合。サイドバーとProjectMainをロードし、このbootstrapクラス:_<div class="animated fadeInUp">
_でサイドバーとProjectMainの小さなアニメーションを取得し、両方のコンポーネントがライフサイクル全体を通過しました。
デフォルトでは、サイドバーでappOverviewが選択されており、CurentProjectAppOverview.vueはProjectMainのコンポーネントとしてロードされます。サイドバーのappSettingsをクリックし、サイドバーのその項目にクラスを追加して選択済みとしてマークし、ProjectMainでCurrentProjectSettings.vueがコンポーネントとしてロードされるよりも。
しかし、パンくずリストには「/ myapps/newversion /:id」に移動するボタンがありますここに問題があります。クリックして「/ myapps/newversion /:id」(router.Push("/myapps/newversion/" + id);
)に移動すると、サイドバーの2番目の項目が選択されたまま(appSettings)で、ProjectMainでCurrentProjectSettings.vueがロードされたままになり、取得できませんサイドバーとProjectMainのbootstrapアニメーション、およびコンポーネントはライフサイクルを通過しません。
「/ myapps/newversion /:id」に移動するためにボタンをクリックするときにここで欲しいのは、私のbootstrapアニメーション(_<div class="animated fadeInUp">
_)です。ライフサイクル。そして、サイドバーでデフォルトのアイテムを選択し(したがってappOverview)、デフォルトのコンポーネントをProjectMainにロードします(したがってCurentProjectAppOverview.vue)。
サイドバーの各アイテムには色付きのボタンがあります。 「/ myapps /:id」から「/ myapps/newversion /:id」に移動する場合、サーバーからCurrentProjectAppOverview.vueにデータをロードし、すべてのデータが満たされている場合はサイドバーのボタンを緑、そうでなければ赤になります。
つまり、この2つのルート間を移動するとき、データをロードして必要なフィールドに入力できるようにしたいので、bootstrapアニメーションとデフォルトビューを選択してロードし、全体を通過する必要がありますライフサイクル。現在、ルーターはそれらをそのまま再利用しています。
そのため、「ReloadComponent:true」、またはコンポーネントを破棄して再作成します。
SidebarProject.vueとProjectMain.vueを複製して名前を変更し、各ルートで基本的にコピーをロードできますが、異なる.vueファイルに同じコードを記述する必要があります。
YouComponent.route.canReuseをfalseに設定するオプションが存在する前に、これは私が望むことをするでしょうが、最新バージョンでは削除されます。
部分的にこれに感謝: https://forum.vuejs.org/t/vue-router-reload-component/4429
私に合った解決策を思いつきました:
最初に、コンポーネントのロード時にアニメーションを再トリガーするbootstrap=に使用される新しい関数を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");
}
}
}
_
コンポーネントがロードされ、ルートがリロードされるか、同じルートのIDが変更されても、コンポーネントが同じままである場合、onCreated();
メソッドを呼び出します。メソッドを再度呼び出します。これにより、新しいデータが処理されます。
bootstrapアニメーションを再トリガーする場合は、アプリの起動時にjQueryに追加するredraw();
関数を使用します。これにより、URLの変更時にアニメーションがトリガーされます。
_$("#breadcrumbsCurrentProject").find(".animated").removeClass("fadeIn").redraw().addClass("fadeIn");
_
私は同じ問題に直面していました。見つけた答えを引用しますが、これは本当にシンプルで素晴らしいものです。最も簡単な解決策は、:key属性を追加することです:
<router-view :key="$route.fullPath"></router-view>
これは、Vue同じコンポーネントがアドレス指定されている場合、ルーターは変更を認識しません。
Vue-routerを使用しているようです。
私はあなたのコードを持っていませんが、私がこれをどのように扱ったかを示すことができます。 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},
],
}
]
})
「default」、「altside」、「toolbar」の名前付きビューがあります。各パスの名前付きビューにコンポーネントを割り当てています。
この後半は、名前を割り当てる親コンポーネントにあります
<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>
だから、私がやったことは、親テンプレートにルータービューの名前付きビューを見るように言ったということです。そして、パスに基づいて、router-mapで指定したコンポーネントをプルします。
「/」パスツールバー==ツールバーコンポーネントですが、「/作成」パスツールバー= eventToolbarコンポーネント。
デフォルトのコンポーネントは動的です。これにより、ツールバーまたは代替コンポーネントを交換せずに子コンポーネントを使用できます。
これは私が思いついたものです:
_import ProjectMain from './templates/ProjectMain.vue';
import SidebarProject from './templates/SidebarProject.vue';
_
//新しいオブジェクトが$.extend({}, OriginalObject);
で個別の.vueファイルとして扱われるようにオブジェクトを浅くコピーします//これは基本的に同じ.vueファイルを作成する必要はありませんが、vue-routerはそれらが異なるため、それらのファイルをリロードします
_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-routerに異なる.vueコンポーネントをロードしていると思わせますが、実際は同じです。そのため、コンポーネント、アニメーション、ライフサイクルのリロードなど、必要なすべてのものを取得できます。複数の類似または同一のコンポーネントを記述する必要はありません。どう思いますか、これがベストプラクティスかどうかはわかりません。