web-dev-qa-db-ja.com

Vue jsは、ルートを変更するときに同じコンポーネントを再レンダリングします

ログインルートとサインアップルートの両方で使用している1つの認証コンポーネントがあります。

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

たとえば、ログインページにいる場合問題は、テキスト入力に何かを入力してサインアップに行くと、テキストがまだそこにある場合、コンポーネントを強制的に再初期化する方法ですか?

12
user7122183

これを行うためのより良い方法は、実際にはルートパスをルータービューのキーにバインドすることです。

<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/[email protected]"></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移行システムを組み合わせることができるため、非常に素晴らしいものになります!

36
GuyC

key 属性を使用してvueを示すことで、一部の要素を再利用する代わりに再レンダリングできます。

例えばAuthコンポーネントに<input/>があり、異なるルートで再レンダリングしたい場合は、keyデータプロップをAuthに追加し、<input :key="key"/>を使用しますテンプレート内。あなたのケースでは、

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

良い選択かもしれません。

5

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がtrueである可能性があります。

0
ahmad molaie