vue.js - Vue 改变路由时重新创建父组件

标签 vue.js vuejs2 vue-router

我在一个项目中使用 Vue.js 和 Vue-router,问题是当路由改变时,包含 router-view 的组件被破坏了。这意味着页面上的所有其他组件都被销毁,所以整个事情看起来就像页面刷新。

我最近开始使用 Vue,我正在处理的应用程序充满了很多遗留代码,很难减少到基础,所以我很难隔离问题。

我试图在 fiddle 中重现该问题,但没有成功。 这是模板代码:

<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',
});

这是 fiddle :https://jsfiddle.net/loorker/m1hncLb0/15/

这是我加载 fiddle 时的控制台日志,点击 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 会在每次路由更改时被销毁并创建,而不是像 fiddle 中那样被更新。

换句话说,考虑 https://v2.vuejs.org/v2/guide/instance.html 中的数字在我的应用程序中发生的情况是,在表示已安装的红色圆圈中,执行流程不采用“数据更改时”路径,而是直接转到“调用 vm.$destroy() 时”。

我尝试将路由器的模式设置为“历史记录”,但它的行为是一样的。应用程序中的任何地方都没有调用 $destroy() 。我没有在路由器 View 上设置 :key 绑定(bind)。

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

谢谢。

最佳答案

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

如所述here :

If you bind key to $route.fullPath, it will always "force a replacement" of the <router-view> element / component every time a navigation event occurs.

关于vue.js - Vue 改变路由时重新创建父组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54351279/

相关文章:

javascript - Vue JS - 将默认值注入(inject)自定义单选组

javascript - 如何使用 Axios 请求的数据填充 Vue 中的数组

javascript - 清除Vue2-Dropzone中的上传区域

vue.js - 如何覆盖 Vuetify 中的 v-btn 事件类?

javascript - Vuetify 自定义验证以确认密码

vue.js - 如何使用 vue-router 处理错误

vue.js - 未知操作 : Counter not incrementing with Vuex (VueJS)

javascript - 在包上安装特定组件(初学者)

vuejs2 - 如何在 vue-router 中对路由进行分组

vue.js - vue-router 和数据属性的理解