Reputation: 1503
When using same components, like two versions of User.vue
which are only different in there data, then when switching between those, there will not be used a created or a mounted lifecycle function in vue.
What i mean:
But, when i switch to a other component, in my case the Welcome.vue
page, and then switching back to to one of my User.vue
components, it works as it should. In this case the User.vue
component will use its own created function and reloads the user related data from my store.
Example:
As you can see the component will be re-rendered and loads his related user data like it should.
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
fetchs his data from a store.state like this:
state: {
users: [
// {
// userName: 'John',
// salary: 2000,
// leftover: 0,
// inc: [],
// exp: [],
// active: false,
// }
],
// placeholder: true
},
The parent is App.vue
with a used <router-link>
for Users.
<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>
And finally my router config, if needed for you
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;
Upvotes: 1
Views: 1695
Reputation: 1731
You are watching $route.params.id
instead of $route.params.userId
, as in router config you have added param as /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
}
},
alternative
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();
}
},
Upvotes: 4