Search code examples
vue.jsvue-componentvue-router

Watch $route.params.id does not trigger re-render of Vue component


I have a Post component which displays user posts. The URL/Route to get to a post is like:

http://localhost:8080/123-todays-bike-ride with 123 being the PostID param in the route.

In my Post.vue component I have the following code:

<template>
    <div>
        <h1>{{Post.PostTitle}}</h1>
        <p>{{Post.Content}}</p>
    </div>
</template>

<script>
    export default {
        name: "Post",
        watch:{
            '$route.params.PostID': function() {
                    this.getPost(); // does not seem to be triggered?
                }
        },
        computed:
            {
                Post() {
                    return this.$store.getters.getPost
                }
            },
        serverPrefetch() {
            return this.getPost();  // to do with SSR
        },
        mounted() {
            if (this.Post == null || !this.Post.length) {
                this.getPost();
            }
        },
        methods: {
            getPost() {
                return this.$store.dispatch('loadPost', {PostID: this.$route.params.PostID})

            }
        }
    }
</script>

The problem is that even if I navigate from http://localhost:8080/123-todays-bike-ride to say http://localhost:8080/999-swimming then the URL in the browser address bar changes but the content of the Post view does not change – it remains with the same content as the 123-todays-bike-ride post.

Clearly the watch: { '$route.params.PostID'... bit is not working, but why and how to solve it?


Solution

  • You can try and make it watch deep:

       watch: {
        "$route.params.PostID": {
          handler: function(value) {
            console.log(value);
          },
          deep: true,
          immediate: true,
        },
      },
    

    Also another way of doing this by re-rendering a component without using watch:

    by adding :key="$route.params.PostID" to the Post component like:

    inside ParentComponent.vue

    <template>
        <Post :key="$route.params.PostID" />
    </template>