Vue js 在更改路由时重新渲染相同的组件

Vue js rerender the same component when changing route

我有一个在登录和注册路径中都使用的身份验证组件。

const routes = [{
  path     : '/',
  name: 'home',
  component: Home
}, {
  path     : '/signin',
  name: 'signin',
  component: Auth
},
  {
    path     : '/signup',
    name: 'signup',
    component: Auth
  }];

例如,如果我在登录页面问题是如果我在文本输入中键入一些内容并转到注册,文本仍然存在,我如何强制组件重新初始化?

vuejs 缓存渲染的组件。您没有提供 Auth 组件代码,但我认为以下内容对您有所帮助。

<template>
     <input type="text" ID="username" v-model="usernameinput">
     <!-- other text boxes and inputs -->
</template>
export default {
    name: 'Auth',
    //component code .....
    data: function() {
        return {
            usernameinput: '',
            //and other stuff
        }
    },
    watch: {
        // call method if the route changes
        '$route': 'reInitialize'
    },
    methods: {
        reInitialize: function() {
            this.usernameinput = '';
            //and so on
        }
    },
    //remainig component code
}

还有另一种可能性,可能是您正在使用动态组件并且 keep-alive 是正确的。

您可以使用 key 属性指示 vue 重新渲染某些元素而不是重复使用它们。

例如你的 Auth 组件中有一个 <input/>,你想在不同的路由下重新渲染,将 key 数据属性添加到 Auth,在模板中使用 <input :key="key"/> .在你这里,

data() {
    key: this.$route.path
}

可能是个不错的选择。

更好的方法实际上是将路由路径绑定到路由器视图的键,即

<router-view :key="$route.path"></router-view>

这样做会强制 Vue 创建组件的新实例。

编辑

已更新以提供您可以添加的元键,这将允许您禁用仅对您需要的路由重用组件。如果您想在深度超过 1 级的路线上使用它,则需要改进 - 但它给了您想法。

const Foo = {
  name: 'foo',
 data () {
     return {
         inputText: '',
        }
    },
 template: `
     <div class="box">
         <h1>{{ $route.path }}</h1>
            <input type="text" v-model="inputText">
        </div>
    `,
}

const Baz = {
  name: 'baz',
 data () {
     return {
         inputText: '',
        }
    },
 template: `
     <div class="box">
         <h1>{{ $route.path }}</h1>
            <input type="text" v-model="inputText">
        </div>
    `,
}

const routes = [
  { path: '/foo', component: Foo, meta: { reuse: false }, },
  { path: '/bar', component: Foo, meta: { reuse: false }, },
  { path: '/baz', component: Baz },
  { path: '/bop', component: Baz }
]

const router = new VueRouter({
  routes
})

const app = new Vue({
  router,
  data: {
    key: null,
  },
}).$mount('#app')

router.beforeEach((to, from, next) => {
  if (to.matched.some(record => record.meta.reuse === false)) {
    app.key = to.path
  } else {
    app.key = null
  }
  next()
})
#content {
    position: relative;   
  height: 200px;
}

.box {
    position: absolute;
    top: 0;
    left: 0;
    width: 200px;
    height: 200px;
    background: rgba(0,0,0, 0.2);
    text-align: center;
    transform: translate3d(0, 0, 0);
}
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@2.0.3"></script>

<div id="app">
  <h1>Hello App!</h1>
  <p>
    <router-link to="/foo">Go to Foo</router-link>
    <router-link to="/bar">Go to Bar</router-link>
    <router-link to="/baz">Go to Baz</router-link>
    <router-link to="/bop">Go to Bop</router-link>
  </p>
  <div id="content">
      <router-view :key="key"></router-view>
  </div>
  <pre>{{ key }}</pre>
</div>

这样您就可以将您的路由器视图与 Vues 转换系统结合起来,让它变得非常棒!

您应该观察路由参数,当它发生变化时,re-execute 以获取数据。 例子

created() {
// watch the params of the route to fetch the data again
this.$watch(
  () => this.$route.params,
  () => {
    this.fetchData()
  },
  // fetch the data when the view is created and the data is
  // already being observed
  { immediate: true }
)

},

更多信息请见https://router.vuejs.org/guide/advanced/data-fetching.html#fetching-after-navigation