当更改路线时,Vue重新创建父组件

时间:2019-01-24 16:29:38

标签: vue.js vuejs2 vue-router

我在项目中将Vue.js与Vue-router一起使用,问题是更改路由时会破坏包含router-view的组件。这意味着页面上的所有其他组件都被破坏了,因此整个过程看起来像页面刷新一样。

我最近开始使用Vue,正在处理的应用程序中充满了许多旧代码,很难简化为基本知识,所以我很难找出问题所在。

我试图重提这个问题,但没有成功。 这是模板代码:

<div id="router-app">
  <router-view></router-view>
</div>

<template id="tricky-place">
  <div>
    <h1>Tricky place</h1>
    <ul>
      <li>
        <router-link to="/panel1">Panel1</router-link>
      </li>
      <li>
        <router-link to="/panel2">Panel2</router-link>
      </li>
    </ul>
    <router-view></router-view>
  </div>
</template>

<template id="tricky-place-panel1">
  <div>
    <h2>Panel1</h2>
  </div>
</template>

<template id="tricky-place-panel2">
  <div>
    <h2>Panel2</h2>
  </div>
</template>

和脚本:

const TrickyPlace = Vue.component('tricky-place', {
    created() {
      console.log("TrickyPlace - created");
    },
    mounted() {
        console.log("TrickyPlace - mounted");
    },
    updated() {
        console.log("TrickyPlace - updated");
    },
    destroyed() {
       console.log("TrickyPlace - destroyed");
    },
  template: '#tricky-place'
});

const TrickyPlacePanel1 = Vue.component('tricky-place-panel1', {
  created() {
    console.log("TrickyPlacePanel1 - created");
  },
  mounted() {
    console.log("TrickyPlacePanel1 - mounted");
  },
  updated() {
    console.log("TrickyPlacePanel1 - updated");
  },
  destroyed() {
    console.log("TrickyPlacePanel1 - destroyed");
  },
  template: '#tricky-place-panel1'
});

const TrickyPlacePanel2 = Vue.component('tricky-place-panel2', {
  created() {
    console.log("TrickyPlacePanel2 - created");
  },
  mounted() {
    console.log("TrickyPlacePanel2 - mounted");
  },
  updated() {
    console.log("TrickyPlacePanel2 - updated");
  },
  destroyed() {
    console.log("TrickyPlacePanel2 - destroyed");
  },
  template: '#tricky-place-panel2'
});

const routes = [{
  path: '/',
  component: TrickyPlace,
  children: [{
    path: 'panel1',
    component: TrickyPlacePanel1
  }, {
    path: 'panel2',
    component: TrickyPlacePanel2
  }, ]
}]
const router = new VueRouter({
  routes
});

const routerApp = new Vue({
  router,
  el: '#router-app',
});

这是小提琴:https://jsfiddle.net/loorker/m1hncLb0/15/

这是加载小提琴时的控制台日志,依次单击Panel1和Panel2:

TrickyPlace - created
TrickyPlace - mounted

TrickyPlacePanel1 - created
TrickyPlacePanel1 - mounted
TrickyPlace - updated

TrickyPlacePanel2 - created
TrickyPlacePanel1 - destroyed
TrickyPlacePanel2 - mounted
TrickyPlace - updated

这是预期的。

这是当我在应用程序中运行相同代码时相同操作顺序的控制台日志:

TrickyPlace - created
TrickyPlace - mounted

TrickyPlace - created
TrickyPlacePanel1 - created
TrickyPlace - destroyed
TrickyPlacePanel1 - mounted
TrickyPlace - mounted

TrickyPlace - created
TrickyPlacePanel2 - created
TrickyPlacePanel1 - destroyed
TrickyPlace - destroyed
TrickyPlacePanel2 - mounted
TrickyPlace - mounted

在每次更改路线时都会破坏并创建TrickyPlace,而不是像在小提琴中一样对其进行更新。

换句话说,考虑到https://vuejs.org/v2/guide/instance.html中的数字,在我的应用程序中发生的事情是,在红色的状态为Mounted的红色圆圈中,执行流程没有采用“数据更改时”的路径,而是直接转到“当调用vm。$ destroy()时”。

我尝试将路由器的模式设置为“历史”,但其行为相同。在应用程序中无处没有$ destroy()的调用。我在路由器视图上没有设置:key绑定。

关于如何继续查找问题的任何想法,为什么要为父级调用创建/销毁而不是仅更新?

谢谢。

1 个答案:

答案 0 :(得分:1)

刚发现问题。组件层次结构中有一个<router-view>,其中:key="$route.fullPath"较高。

here所述:

  

如果将key绑定到$route.fullPath,它将始终“强制   每个<router-view>元素/组件的替换”   导航事件发生的时间。