Vue переключение между одинаковыми компонентами в просмотре маршрутизатора не будет снова смонтировано / создано - PullRequest
0 голосов
/ 21 марта 2020

При использовании одних и тех же компонентов, например двух версий User.vue, которые различаются только в этих данных, при переключении между ними не будет использоваться созданная или смонтированная функция жизненного цикла в vue.

Что я имею в виду:

no changes


Но, когда я переключаюсь на другой компонент, в моем случае страница Welcome.vue, и затем переключение обратно на один из моих User.vue компонентов, все работает как надо. В этом случае компонент User.vue будет использовать собственную созданную функцию и перезагружает связанные с пользователем данные из моего хранилища.

Пример:

how it works


Как видите, компонент будет перерисован и загружает связанные с ним пользовательские данные, как и должно быть.

my User.vue component

<template>
  <div>
    <UserInfo
      :user-name="userName"
      :budget="budget"
    />
    <UserIncExp />
  </div>
</template>

<script>
import UserInfo from '../User/UserInfo.vue';
import UserIncExp from '../User/UserIncExp/_UserIncExp.vue';
export default {
  components: {
    UserInfo,
    UserIncExp
  },
  data() {
    return {
      userName: '',
      budget: ''
    };
  },
  computed: {

  },
  watch: {
    '$route.params.id': id => {
      console.log(id);
      this.loadUserDataFromState();
    }
    // this.userName = this.$store.state.users[this.$attrs.userId].userName;
    // console.log(this.userId);
  },
  created: function() {
    this.loadUserDataFromState();
  },
  methods: {
    loadUserDataFromState() {
      console.log('route changed');
      this.userName = this.$store.state.users[this.$attrs.userId].userName;
      this.budget = this.$store.state.users[this.$attrs.userId].salery;
      console.log(this.userName);
      console.log(this.budget);
    }
  },
};
</script>

<style>
</style>

User.vue получает свои данные из store.state следующим образом:

  state: {
    users: [
      // {
      //   userName: 'John',
      //   salary: 2000,
      //   leftover: 0,
      //   inc: [],
      //   exp: [],
      //   active: false,
      // }
    ],
    // placeholder: true
  },

Родитель App.vue с использованным <router-link> для пользователей.

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

<script>
// import { mapState } from 'vuex';
import Navigation from './components/Navigation/_Navigation.vue';
export default {
  components: {
    Navigation
  },
  computed: {}
};
</script>

<style lang="scss">
#app {
  height: 1200px;
  width: 100vw;
  background-color: $dark;
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #ffffff;
  a:hover {
    color: $orange;
  }
  a {
    color: $white;
  }
  *:focus {
    box-shadow: 0 0 0 0.2rem rgba(233, 84, 32, 0) !important;
  }
}
</style>

И, наконец, моя конфигурация маршрутизатора, если нужно для вас

import Vue from 'vue';
import VueRouter from 'vue-router';
import Welcome from '../views/Welcome.vue';
import User from '../components/User/_User.vue';

Vue.use(VueRouter);

const routes = [
  {
    path: '/',
    name: 'Welcome',
    component: Welcome
  },
  {
    path: '/user/:userId',
    name: 'User',
    component: User,
    props: true
  }
];

const router = new VueRouter({
  // mode: 'history',
  base: process.env.BASE_URL,
  routes
});

export default router;

1 Ответ

2 голосов
/ 21 марта 2020

Вы смотрите $route.params.id вместо $route.params.userId, так как в конфигурации маршрутизатора вы добавили параметр как /user/:userId

watch: {
  "$route.params.userId": { // <-- here 
    handler () {
      this.loadUserDataFromState();
    },
    immediate: true // will call handler on component mount / create as well, so no need to call fn on mounted again
    }
  },

альтернатива

beforeRouteUpdate (to, from, next) {
 if (from.name === to.name) { // Call fn only when: route hasn't changed instead just query/params for the route has changed
  this.loadUserDataFromState();
 }
},
...